Feathers: Very slow throughput

Created on 19 Apr 2019  ยท  7Comments  ยท  Source: feathersjs/feathers

Steps to reproduce

  1. Install autocannon.

  2. Create a file fastify.js with the following content (this is for the test baseline, using another framework):

// Require the framework and instantiate it                                      
const fastify = require('fastify/fastify')({ logger: false })                    

// Declare a route                                                               
fastify.post('/users-without-db', async (request, reply) => {                    
    return { hello: 'world' }                                                    
})                                                                               

// Run the server!                                                               
const start = async () => {                                                      
    try {                                                                        
        await fastify.listen(3030)                                               
        fastify.log.info(`server listening on ${fastify.server.address().port}`) 
    } catch (err) {                                                              
        fastify.log.error(err)                                                   
        process.exit(1)                                                          
    }                                                                            
}                                                                                
start()                                                                          
  1. Run Nodejs:
node fastify.js
  1. Run autocannon agaist the Node service:
[root@server]# autocannon -c 100 -H Content-Type=application/json -i body.json -m POST http://localhost:3030/users-without-db
Running 10s test @ http://localhost:3030/users-without-db
100 connections

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Stat    โ”‚ 2.5% โ”‚ 50%   โ”‚ 97.5% โ”‚ 99%   โ”‚ Avg      โ”‚ Stdev   โ”‚ Max      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Latency โ”‚ 6 ms โ”‚ 10 ms โ”‚ 22 ms โ”‚ 28 ms โ”‚ 10.95 ms โ”‚ 4.36 ms โ”‚ 71.05 ms โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Stat      โ”‚ 1%     โ”‚ 2.5%   โ”‚ 50%     โ”‚ 97.5%   โ”‚ Avg     โ”‚ Stdev   โ”‚ Min    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Req/Sec   โ”‚ 5471   โ”‚ 5471   โ”‚ 8919    โ”‚ 9999    โ”‚ 8738.8  โ”‚ 1236.16 โ”‚ 5470   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Bytes/Sec โ”‚ 898 kB โ”‚ 898 kB โ”‚ 1.46 MB โ”‚ 1.64 MB โ”‚ 1.43 MB โ”‚ 203 kB  โ”‚ 897 kB โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Req/Bytes counts sampled once per second.

87k requests in 10.08s, 14.3 MB read
  1. Note the average requests per second using that framework: 8738.8 req/s.

  2. Stop Node.

  3. Create a file feathers.js with the following content:

const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const socketio = require('@feathersjs/socketio');
const app = express(feathers());

const appPort = 3030;
app.use(express.json());
app.use(express.urlencoded({extended: true}));
app.configure(express.rest());
app.configure(socketio());
app.use(express.errorHandler());
app.use(express.errorHandler());

class UsersWithoutDB {

    async create(data, params) {
        return data
    }
}

app.use('/users-without-db', new UsersWithoutDB());

app.listen(appPort).on('listening', () => {
    console.log(`Server listening on localhost:${appPort}`);
});
  1. Run Nodejs:
node feathers.js
  1. Run autocannon agaist the Node service:
[root@server]# autocannon -c 100 -H Content-Type=application/json -i body.json -m POST http://localhost:3030/users-without-db
Running 10s test @ http://localhost:3030/users-without-db
100 connections

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Stat    โ”‚ 2.5%  โ”‚ 50%   โ”‚ 97.5% โ”‚ 99%   โ”‚ Avg      โ”‚ Stdev    โ”‚ Max       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Latency โ”‚ 22 ms โ”‚ 28 ms โ”‚ 72 ms โ”‚ 89 ms โ”‚ 32.02 ms โ”‚ 13.06 ms โ”‚ 166.81 ms โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Stat      โ”‚ 1%     โ”‚ 2.5%   โ”‚ 50%    โ”‚ 97.5%   โ”‚ Avg    โ”‚ Stdev  โ”‚ Min    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Req/Sec   โ”‚ 1334   โ”‚ 1334   โ”‚ 3355   โ”‚ 3795    โ”‚ 3079.7 โ”‚ 815.78 โ”‚ 1334   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Bytes/Sec โ”‚ 370 kB โ”‚ 370 kB โ”‚ 929 kB โ”‚ 1.05 MB โ”‚ 853 kB โ”‚ 226 kB โ”‚ 370 kB โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Req/Bytes counts sampled once per second.

31k requests in 10.09s, 8.53 MB read
  1. Notice that the requests per second of the service using Feathers is very low, around 3000 requests per second. Another framework have higher throughput in the same server.

Expected behavior

I believe that the throughput should be higher than 3000 requests per second, I have seen many benchmarks reporting much higher values.

Actual behavior

The throughput is very low.

System configuration

CPU Intel Core i7 8650 2.11 GHz, 4 cores, 32 GB RAM, SSD, Windows 10 64 bits.

Module versions (especially the part that's not working):

@feathersjs/[email protected]
@feathersjs/[email protected]
@feathersjs/[email protected]

NodeJS version: v10.15.3

Operating System: Centos 7

Browser Version: N/A

React Native Version: N/A

Module Loader: require

Most helpful comment

The next version will add the option to use Koa instead of Express as the underlying HTTP framework. It uses the same radix tree router that is already used for Feathers websocket transports and will probably allow a similar throughput to Fastify. The work in progress branch is https://github.com/feathersjs/feathers/tree/koa.

All 7 comments

Since Feathers does not add a lot of overhead, these are probably the same number as for any other Express application. If you are concerned about performance you should use Feathers with websockets which can be 2 to 200 times faster than even Fastify as shown in this comparison.

Feathers v4 will also come with a native HTTP2 adapter which should provide similar (and probably better) numbers.

Hi @daffl, thanks for the information. Yes, that's true about websockets, it's really amazing but I need the REST API. Feathers is the best framework in terms of simplicity to create REST APIs.

You are right about the equivalent performance of Express. I have gotten similar numbers. I tested Feathers and Express on a Linux server, VPS. It's also slow! It seems that the only way to get that high numbers (above 30k req/s) is to use a server with very high end specs.

Please let me know if that makes sense.

Hi @averri,
Instead of scale up as you mentioned, I think scale out ( add more servers ) is a better option?

The next version will add the option to use Koa instead of Express as the underlying HTTP framework. It uses the same radix tree router that is already used for Feathers websocket transports and will probably allow a similar throughput to Fastify. The work in progress branch is https://github.com/feathersjs/feathers/tree/koa.

@daffl, I have seen benchmarks of Koa outperforming Express by a small margin, do you have a roadmap to share? I'm quite happy with the set of features of Feathers. I think it should continue focusing on providing a transport agnostic API and do it well, as it already does.

I agree with @viettd, scaling out is the way to go, especially because in a real application it's unlikely that a single service will sustain a very high throughput using just one server.

In general, since a Feathers transport adapter does not really add much overhead, it will be about as fast as the underlying framework being used. The new authentication makes it much easier to implement a new transport with Koa being the first. This is one of the nice things about Feathers. You can choose the most suitable available transport without having to change anything in your application itself.

I also think it is worth noting that plain throughput will probably not matter that much as soon as you make a database request or even just add authentication. Almost all performance problems I have ever encountered were inefficient database queries not anything at the HTTP framework level.

Did Koa support arrive in feathers v4? Is there a working example somewhere, maybe with authentication and rest? Or are there other options than using express?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

arve0 picture arve0  ยท  4Comments

rstegg picture rstegg  ยท  3Comments

jordanbtucker picture jordanbtucker  ยท  4Comments

codeus-de picture codeus-de  ยท  4Comments

RickEyre picture RickEyre  ยท  4Comments