├── .gitignore ├── README.md ├── Vagrantfile ├── app ├── __init__.py ├── main.py ├── models.py ├── templates │ └── fortune.jinja └── views.py ├── process.py ├── remote-setup ├── data.sql ├── requirements.txt ├── serve.py └── setup.sh ├── results.json └── run.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | .tox/ 3 | env/ 4 | *.egg-info/ 5 | gunicorn.pid 6 | gunicorn.log 7 | .idea/ 8 | .vagrant/ 9 | benchmarks.pem 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # aiohttp benchmarks 2 | 3 | 4 | ## Usage 5 | 6 | ```shell 7 | virtualenv -p `which python3` env 8 | . env/bin/activate 9 | pip install requests 10 | ``` 11 | 12 | **With vagrant:** 13 | 14 | ```shell 15 | vagrant up 16 | python run.py 17 | python process.py 18 | ``` 19 | 20 | **With a remote machine:** 21 | 22 | (this assumes you have a pem file `benchmarks.pem` for connecting to the remote host in the current directory.) 23 | 24 | ```shell 25 | export REMOTE=true 26 | export SSH_ADDRESS="@" 27 | export HTTP_ADDRESS="http://" 28 | scp -i benchmarks.pem -r app $SSH_ADDRESS: 29 | scp -i benchmarks.pem -r remote-setup $SSH_ADDRESS: 30 | ssh -i benchmarks.pem $SSH_ADDRESS remote-setup/setup.sh 31 | 32 | # everything should now be setup, you can run the server 33 | ssh -i benchmarks.pem $SSH_ADDRESS "sudo ~/env38/bin/python server.py" 34 | # now open $HTTP_ADDRESS/plaintext in your browser and check the server is working. 35 | 36 | python run.py 37 | python process.py 38 | ``` 39 | 40 | # Results 2020-12-27 - remote server 41 | 42 | Tests were run between two aws `t2.medium` in `eu-west` running the standard ubuntu 20.04 ami. 43 | Performance is measured in RPC (requests per second). So **the higher** the number the better. 44 | 45 | ### Comparing aiohttp versions 46 | 47 | ``` 48 | URL python DB queries Conc 3.6 3.7 49 | /json 3.7 - - 32 7,140 6,723 | -6% 50 | /json 3.7 - - 64 7,143 7,335 | 3% 51 | /json 3.7 - - 128 7,565 5,894 |-22% 52 | /json 3.7 - - 256 6,938 6,538 | -6% 53 | 54 | /plaintext 3.7 - - 32 7,056 6,714 | -5% 55 | /plaintext 3.7 - - 64 6,938 6,848 | -1% 56 | /plaintext 3.7 - - 128 6,398 5,996 | -6% 57 | /plaintext 3.7 - - 256 6,975 6,425 | -8% 58 | 59 | /{c}/db 3.7 orm - 32 1,148 1,123 | -2% 60 | /{c}/db 3.7 orm - 64 1,103 1,150 | 4% 61 | /{c}/db 3.7 orm - 128 1,095 1,145 | 5% 62 | /{c}/db 3.7 orm - 256 1,067 1,096 | 3% 63 | /{c}/db 3.7 raw - 32 2,460 2,407 | -2% 64 | /{c}/db 3.7 raw - 64 2,339 2,310 | -1% 65 | /{c}/db 3.7 raw - 128 2,494 2,300 | -8% 66 | /{c}/db 3.7 raw - 256 2,318 2,298 | -1% 67 | 68 | /{c}/fortunes 3.7 orm - 32 885 899 | 2% 69 | /{c}/fortunes 3.7 orm - 64 893 862 | -4% 70 | /{c}/fortunes 3.7 orm - 128 866 891 | 3% 71 | /{c}/fortunes 3.7 orm - 256 864 837 | -3% 72 | /{c}/fortunes 3.7 raw - 32 1,588 1,582 | -0% 73 | /{c}/fortunes 3.7 raw - 64 1,559 1,549 | -1% 74 | /{c}/fortunes 3.7 raw - 128 1,543 1,525 | -1% 75 | /{c}/fortunes 3.7 raw - 256 1,474 1,555 | 5% 76 | 77 | /{c}/queries/{q} 3.7 orm 5 256 330 330 | -0% 78 | /{c}/queries/{q} 3.7 orm 10 256 170 169 | -1% 79 | /{c}/queries/{q} 3.7 orm 20 256 85 82 | -3% 80 | /{c}/queries/{q} 3.7 raw 5 256 1,091 1,090 | -0% 81 | /{c}/queries/{q} 3.7 raw 10 256 815 876 | 8% 82 | /{c}/queries/{q} 3.7 raw 20 256 571 611 | 7% 83 | 84 | /{c}/updates/{q} 3.7 orm 5 256 168 164 | -2% 85 | /{c}/updates/{q} 3.7 orm 10 256 96 83 |-13% 86 | /{c}/updates/{q} 3.7 orm 20 256 49 50 | 1% 87 | /{c}/updates/{q} 3.7 raw 5 256 724 779 | 7% 88 | /{c}/updates/{q} 3.7 raw 10 256 478 493 | 3% 89 | /{c}/updates/{q} 3.7 raw 20 256 277 312 | 13% 90 | 91 | /json 3.8 - - 32 8,558 7,199 |-16% 92 | /json 3.8 - - 64 9,278 8,626 | -7% 93 | /json 3.8 - - 128 8,045 7,310 | -9% 94 | /json 3.8 - - 256 8,511 7,472 |-12% 95 | 96 | /plaintext 3.8 - - 32 7,306 7,151 | -2% 97 | /plaintext 3.8 - - 64 7,840 9,219 | 18% 98 | /plaintext 3.8 - - 128 8,649 9,536 | 10% 99 | /plaintext 3.8 - - 256 8,820 8,795 | -0% 100 | 101 | /{c}/db 3.8 orm - 32 1,279 1,360 | 6% 102 | /{c}/db 3.8 orm - 64 1,288 1,283 | -0% 103 | /{c}/db 3.8 orm - 128 1,232 1,240 | 1% 104 | /{c}/db 3.8 orm - 256 1,217 1,267 | 4% 105 | /{c}/db 3.8 raw - 32 2,777 2,781 | 0% 106 | /{c}/db 3.8 raw - 64 2,600 2,668 | 3% 107 | /{c}/db 3.8 raw - 128 2,645 2,751 | 4% 108 | /{c}/db 3.8 raw - 256 2,516 2,565 | 2% 109 | 110 | /{c}/fortunes 3.8 orm - 32 1,047 1,051 | 0% 111 | /{c}/fortunes 3.8 orm - 64 1,025 985 | -4% 112 | /{c}/fortunes 3.8 orm - 128 969 1,010 | 4% 113 | /{c}/fortunes 3.8 orm - 256 974 1,015 | 4% 114 | /{c}/fortunes 3.8 raw - 32 1,781 1,759 | -1% 115 | /{c}/fortunes 3.8 raw - 64 1,637 1,714 | 5% 116 | /{c}/fortunes 3.8 raw - 128 1,688 1,771 | 5% 117 | /{c}/fortunes 3.8 raw - 256 1,677 1,647 | -2% 118 | 119 | /{c}/queries/{q} 3.8 orm 5 256 401 407 | 1% 120 | /{c}/queries/{q} 3.8 orm 10 256 205 198 | -3% 121 | /{c}/queries/{q} 3.8 orm 20 256 98 101 | 2% 122 | /{c}/queries/{q} 3.8 raw 5 256 1,110 1,191 | 7% 123 | /{c}/queries/{q} 3.8 raw 10 256 844 847 | 0% 124 | /{c}/queries/{q} 3.8 raw 20 256 593 596 | 0% 125 | 126 | /{c}/updates/{q} 3.8 orm 5 256 194 201 | 4% 127 | /{c}/updates/{q} 3.8 orm 10 256 100 102 | 3% 128 | /{c}/updates/{q} 3.8 orm 20 256 55 58 | 4% 129 | /{c}/updates/{q} 3.8 raw 5 256 786 777 | -1% 130 | /{c}/updates/{q} 3.8 raw 10 256 521 523 | 0% 131 | /{c}/updates/{q} 3.8 raw 20 256 314 314 | 0% 132 | 133 | /json 3.9 - - 32 8,616 7,951 | -8% 134 | /json 3.9 - - 64 8,466 9,366 | 11% 135 | /json 3.9 - - 128 9,670 7,642 |-21% 136 | /json 3.9 - - 256 7,685 8,055 | 5% 137 | 138 | /plaintext 3.9 - - 32 9,365 7,795 |-17% 139 | /plaintext 3.9 - - 64 10,148 8,799 |-13% 140 | /plaintext 3.9 - - 128 10,091 7,654 |-24% 141 | /plaintext 3.9 - - 256 8,263 7,007 |-15% 142 | 143 | /{c}/db 3.9 orm - 32 1,311 1,348 | 3% 144 | /{c}/db 3.9 orm - 64 1,315 1,263 | -4% 145 | /{c}/db 3.9 orm - 128 1,236 1,312 | 6% 146 | /{c}/db 3.9 orm - 256 1,297 1,291 | -0% 147 | /{c}/db 3.9 raw - 32 2,799 2,667 | -5% 148 | /{c}/db 3.9 raw - 64 2,713 2,594 | -4% 149 | /{c}/db 3.9 raw - 128 2,530 2,491 | -2% 150 | /{c}/db 3.9 raw - 256 2,573 2,505 | -3% 151 | 152 | /{c}/fortunes 3.9 orm - 32 995 1,014 | 2% 153 | /{c}/fortunes 3.9 orm - 64 1,016 1,014 | -0% 154 | /{c}/fortunes 3.9 orm - 128 1,035 1,032 | -0% 155 | /{c}/fortunes 3.9 orm - 256 1,007 995 | -1% 156 | /{c}/fortunes 3.9 raw - 32 1,727 1,766 | 2% 157 | /{c}/fortunes 3.9 raw - 64 1,672 1,669 | -0% 158 | /{c}/fortunes 3.9 raw - 128 1,619 1,630 | 1% 159 | /{c}/fortunes 3.9 raw - 256 1,581 1,676 | 6% 160 | 161 | /{c}/queries/{q} 3.9 orm 5 256 393 382 | -3% 162 | /{c}/queries/{q} 3.9 orm 10 256 194 193 | -1% 163 | /{c}/queries/{q} 3.9 orm 20 256 96 99 | 2% 164 | /{c}/queries/{q} 3.9 raw 5 256 1,102 1,098 | -0% 165 | /{c}/queries/{q} 3.9 raw 10 256 871 872 | 0% 166 | /{c}/queries/{q} 3.9 raw 20 256 572 593 | 4% 167 | 168 | /{c}/updates/{q} 3.9 orm 5 256 214 201 | -6% 169 | /{c}/updates/{q} 3.9 orm 10 256 104 102 | -3% 170 | /{c}/updates/{q} 3.9 orm 20 256 58 57 | -0% 171 | /{c}/updates/{q} 3.9 raw 5 256 744 789 | 6% 172 | /{c}/updates/{q} 3.9 raw 10 256 497 519 | 4% 173 | /{c}/updates/{q} 3.9 raw 20 256 306 305 | -0% 174 | ``` 175 | 176 | ### Comparing python versions 177 | 178 | ``` 179 | URL aiohttp DB queries Conc 3.7 3.8 3.9 180 | /json 3.6 - - 32 7,140 8,558 | 20% 8,616 | 21% 181 | /json 3.6 - - 64 7,143 9,278 | 30% 8,466 | 19% 182 | /json 3.6 - - 128 7,565 8,045 | 6% 9,670 | 28% 183 | /json 3.6 - - 256 6,938 8,511 | 23% 7,685 | 11% 184 | 185 | /plaintext 3.6 - - 32 7,056 7,306 | 4% 9,365 | 33% 186 | /plaintext 3.6 - - 64 6,938 7,840 | 13% 10,148 | 46% 187 | /plaintext 3.6 - - 128 6,398 8,649 | 35% 10,091 | 58% 188 | /plaintext 3.6 - - 256 6,975 8,820 | 26% 8,263 | 18% 189 | 190 | /{c}/db 3.6 orm - 32 1,148 1,279 | 11% 1,311 | 14% 191 | /{c}/db 3.6 orm - 64 1,103 1,288 | 17% 1,315 | 19% 192 | /{c}/db 3.6 orm - 128 1,095 1,232 | 13% 1,236 | 13% 193 | /{c}/db 3.6 orm - 256 1,067 1,217 | 14% 1,297 | 22% 194 | /{c}/db 3.6 raw - 32 2,460 2,777 | 13% 2,799 | 14% 195 | /{c}/db 3.6 raw - 64 2,339 2,600 | 11% 2,713 | 16% 196 | /{c}/db 3.6 raw - 128 2,494 2,645 | 6% 2,530 | 1% 197 | /{c}/db 3.6 raw - 256 2,318 2,516 | 9% 2,573 | 11% 198 | 199 | /{c}/fortunes 3.6 orm - 32 885 1,047 | 18% 995 | 12% 200 | /{c}/fortunes 3.6 orm - 64 893 1,025 | 15% 1,016 | 14% 201 | /{c}/fortunes 3.6 orm - 128 866 969 | 12% 1,035 | 20% 202 | /{c}/fortunes 3.6 orm - 256 864 974 | 13% 1,007 | 17% 203 | /{c}/fortunes 3.6 raw - 32 1,588 1,781 | 12% 1,727 | 9% 204 | /{c}/fortunes 3.6 raw - 64 1,559 1,637 | 5% 1,672 | 7% 205 | /{c}/fortunes 3.6 raw - 128 1,543 1,688 | 9% 1,619 | 5% 206 | /{c}/fortunes 3.6 raw - 256 1,474 1,677 | 14% 1,581 | 7% 207 | 208 | /{c}/queries/{q} 3.6 orm 5 256 330 401 | 21% 393 | 19% 209 | /{c}/queries/{q} 3.6 orm 10 256 170 205 | 20% 194 | 14% 210 | /{c}/queries/{q} 3.6 orm 20 256 85 98 | 16% 96 | 13% 211 | /{c}/queries/{q} 3.6 raw 5 256 1,091 1,110 | 2% 1,102 | 1% 212 | /{c}/queries/{q} 3.6 raw 10 256 815 844 | 4% 871 | 7% 213 | /{c}/queries/{q} 3.6 raw 20 256 571 593 | 4% 572 | 0% 214 | 215 | /{c}/updates/{q} 3.6 orm 5 256 168 194 | 16% 214 | 28% 216 | /{c}/updates/{q} 3.6 orm 10 256 96 100 | 4% 104 | 9% 217 | /{c}/updates/{q} 3.6 orm 20 256 49 55 | 13% 58 | 17% 218 | /{c}/updates/{q} 3.6 raw 5 256 724 786 | 8% 744 | 3% 219 | /{c}/updates/{q} 3.6 raw 10 256 478 521 | 9% 497 | 4% 220 | /{c}/updates/{q} 3.6 raw 20 256 277 314 | 13% 306 | 10% 221 | 222 | /json 3.7 - - 32 6,723 7,199 | 7% 7,951 | 18% 223 | /json 3.7 - - 64 7,335 8,626 | 18% 9,366 | 28% 224 | /json 3.7 - - 128 5,894 7,310 | 24% 7,642 | 30% 225 | /json 3.7 - - 256 6,538 7,472 | 14% 8,055 | 23% 226 | 227 | /plaintext 3.7 - - 32 6,714 7,151 | 7% 7,795 | 16% 228 | /plaintext 3.7 - - 64 6,848 9,219 | 35% 8,799 | 28% 229 | /plaintext 3.7 - - 128 5,996 9,536 | 59% 7,654 | 28% 230 | /plaintext 3.7 - - 256 6,425 8,795 | 37% 7,007 | 9% 231 | 232 | /{c}/db 3.7 orm - 32 1,123 1,360 | 21% 1,348 | 20% 233 | /{c}/db 3.7 orm - 64 1,150 1,283 | 12% 1,263 | 10% 234 | /{c}/db 3.7 orm - 128 1,145 1,240 | 8% 1,312 | 15% 235 | /{c}/db 3.7 orm - 256 1,096 1,267 | 16% 1,291 | 18% 236 | /{c}/db 3.7 raw - 32 2,407 2,781 | 16% 2,667 | 11% 237 | /{c}/db 3.7 raw - 64 2,310 2,668 | 15% 2,594 | 12% 238 | /{c}/db 3.7 raw - 128 2,300 2,751 | 20% 2,491 | 8% 239 | /{c}/db 3.7 raw - 256 2,298 2,565 | 12% 2,505 | 9% 240 | 241 | /{c}/fortunes 3.7 orm - 32 899 1,051 | 17% 1,014 | 13% 242 | /{c}/fortunes 3.7 orm - 64 862 985 | 14% 1,014 | 18% 243 | /{c}/fortunes 3.7 orm - 128 891 1,010 | 13% 1,032 | 16% 244 | /{c}/fortunes 3.7 orm - 256 837 1,015 | 21% 995 | 19% 245 | /{c}/fortunes 3.7 raw - 32 1,582 1,759 | 11% 1,766 | 12% 246 | /{c}/fortunes 3.7 raw - 64 1,549 1,714 | 11% 1,669 | 8% 247 | /{c}/fortunes 3.7 raw - 128 1,525 1,771 | 16% 1,630 | 7% 248 | /{c}/fortunes 3.7 raw - 256 1,555 1,647 | 6% 1,676 | 8% 249 | 250 | /{c}/queries/{q} 3.7 orm 5 256 330 407 | 23% 382 | 16% 251 | /{c}/queries/{q} 3.7 orm 10 256 169 198 | 17% 193 | 14% 252 | /{c}/queries/{q} 3.7 orm 20 256 82 101 | 22% 99 | 20% 253 | /{c}/queries/{q} 3.7 raw 5 256 1,090 1,191 | 9% 1,098 | 1% 254 | /{c}/queries/{q} 3.7 raw 10 256 876 847 | -3% 872 | -0% 255 | /{c}/queries/{q} 3.7 raw 20 256 611 596 | -2% 593 | -3% 256 | 257 | /{c}/updates/{q} 3.7 orm 5 256 164 201 | 23% 201 | 23% 258 | /{c}/updates/{q} 3.7 orm 10 256 83 102 | 23% 102 | 22% 259 | /{c}/updates/{q} 3.7 orm 20 256 50 58 | 16% 57 | 16% 260 | /{c}/updates/{q} 3.7 raw 5 256 779 777 | -0% 789 | 1% 261 | /{c}/updates/{q} 3.7 raw 10 256 493 523 | 6% 519 | 5% 262 | /{c}/updates/{q} 3.7 raw 20 256 312 314 | 1% 305 | -2% 263 | ``` 264 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.configure(2) do |config| 5 | config.vm.box = "bento/ubuntu-20.04" 6 | config.vm.network "forwarded_port", guest: 80, host: 8080 7 | config.vm.provision "bootstrap", type: "shell", privileged: false do |s| 8 | s.inline = "bash /vagrant/remote-setup/setup.sh" 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aio-libs/aiohttp-benchmarks/018d6a3dd9a343c0b1f1408b71ef4dd1d4d7a7fc/app/__init__.py -------------------------------------------------------------------------------- /app/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import aiohttp_jinja2 5 | import aiopg.sa 6 | import asyncpg 7 | import jinja2 8 | from aiohttp import web 9 | from sqlalchemy.engine.url import URL 10 | 11 | from .views import ( 12 | json, 13 | single_database_query_orm, 14 | multiple_database_queries_orm, 15 | fortunes, 16 | updates, 17 | plaintext, 18 | 19 | single_database_query_raw, 20 | multiple_database_queries_raw, 21 | fortunes_raw, 22 | updates_raw, 23 | ) 24 | 25 | THIS_DIR = Path(__file__).parent 26 | 27 | 28 | def pg_dsn() -> str: 29 | """ 30 | :return: DSN url suitable for sqlalchemy and aiopg. 31 | """ 32 | return str(URL( 33 | database='hello_world', 34 | password=os.getenv('PGPASS', 'benchmarks'), 35 | host='localhost', 36 | port='5432', 37 | username=os.getenv('PGUSER', 'postgres'), 38 | drivername='postgres', 39 | )) 40 | 41 | 42 | async def startup(app: web.Application): 43 | dsn = pg_dsn() 44 | min_size, max_size = 10, 20 45 | app['pg_orm'] = await aiopg.sa.create_engine(dsn=dsn, minsize=min_size, maxsize=max_size) 46 | app['pg_raw'] = await asyncpg.create_pool(dsn=dsn, min_size=min_size, max_size=max_size) 47 | 48 | 49 | async def cleanup(app: web.Application): 50 | app['pg_orm'].close() 51 | await app['pg_orm'].wait_closed() 52 | await app['pg_raw'].close() 53 | 54 | 55 | def setup_routes(app): 56 | app.router.add_get('/json', json) 57 | app.router.add_get('/plaintext', plaintext) 58 | 59 | app.router.add_get('/orm/db', single_database_query_orm) 60 | app.router.add_get('/orm/queries/{queries:.*}', multiple_database_queries_orm) 61 | app.router.add_get('/orm/fortunes', fortunes) 62 | app.router.add_get('/orm/updates/{queries:.*}', updates) 63 | 64 | app.router.add_get('/raw/db', single_database_query_raw) 65 | app.router.add_get('/raw/queries/{queries:.*}', multiple_database_queries_raw) 66 | app.router.add_get('/raw/fortunes', fortunes_raw) 67 | app.router.add_get('/raw/updates/{queries:.*}', updates_raw) 68 | 69 | 70 | def create_app(): 71 | app = web.Application() 72 | 73 | jinja2_loader = jinja2.FileSystemLoader(str(THIS_DIR / 'templates')) 74 | aiohttp_jinja2.setup(app, loader=jinja2_loader) 75 | 76 | app.on_startup.append(startup) 77 | app.on_cleanup.append(cleanup) 78 | 79 | setup_routes(app) 80 | return app 81 | -------------------------------------------------------------------------------- /app/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, Integer, String 2 | from sqlalchemy.ext.declarative import declarative_base 3 | 4 | Base = declarative_base() 5 | 6 | 7 | class World(Base): 8 | __tablename__ = 'world' 9 | id = Column(Integer, primary_key=True) 10 | randomnumber = Column(Integer) 11 | 12 | sa_worlds = World.__table__ 13 | 14 | 15 | class Fortune(Base): 16 | __tablename__ = 'fortune' 17 | id = Column(Integer, primary_key=True) 18 | message = Column(String) 19 | 20 | sa_fortunes = Fortune.__table__ 21 | -------------------------------------------------------------------------------- /app/templates/fortune.jinja: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Fortunes 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {% for fortune in fortunes %} 13 | 14 | 15 | 16 | 17 | {% endfor %} 18 |
idmessage
{{ fortune.id }}{{ fortune.message|escape }}
19 | 20 | 21 | -------------------------------------------------------------------------------- /app/views.py: -------------------------------------------------------------------------------- 1 | from operator import attrgetter, itemgetter 2 | from random import randint 3 | 4 | from aiohttp_jinja2 import template 5 | from aiohttp.web import Response 6 | import ujson 7 | 8 | from sqlalchemy import select 9 | 10 | from .models import sa_fortunes, sa_worlds, Fortune 11 | 12 | 13 | def json_response(data): 14 | body = ujson.dumps(data) 15 | return Response(body=body.encode(), content_type='application/json') 16 | 17 | 18 | def get_num_queries(request): 19 | try: 20 | num_queries = int(request.match_info.get('queries', 1)) 21 | except ValueError: 22 | return 1 23 | if num_queries < 1: 24 | return 1 25 | if num_queries > 500: 26 | return 500 27 | return num_queries 28 | 29 | 30 | async def json(request): 31 | """ 32 | Test 1 33 | """ 34 | return json_response({'message': 'Hello, World!'}) 35 | 36 | 37 | async def single_database_query_orm(request): 38 | """ 39 | Test 2 ORM 40 | """ 41 | id_ = randint(1, 10000) 42 | async with request.app['pg_orm'].acquire() as conn: 43 | cur = await conn.execute(select([sa_worlds.c.randomnumber]).where(sa_worlds.c.id == id_)) 44 | r = await cur.first() 45 | return json_response({'id': id_, 'randomNumber': r[0]}) 46 | 47 | 48 | async def single_database_query_raw(request): 49 | """ 50 | Test 2 RAW 51 | """ 52 | id_ = randint(1, 10000) 53 | 54 | async with request.app['pg_raw'].acquire() as conn: 55 | r = await conn.fetchval('SELECT randomnumber FROM world WHERE id = $1', id_) 56 | return json_response({'id': id_, 'randomNumber': r}) 57 | 58 | 59 | async def multiple_database_queries_orm(request): 60 | """ 61 | Test 3 ORM 62 | """ 63 | num_queries = get_num_queries(request) 64 | 65 | ids = [randint(1, 10000) for _ in range(num_queries)] 66 | ids.sort() 67 | 68 | result = [] 69 | async with request.app['pg_orm'].acquire() as conn: 70 | for id_ in ids: 71 | cur = await conn.execute(select([sa_worlds.c.randomnumber]).where(sa_worlds.c.id == id_)) 72 | r = await cur.first() 73 | result.append({'id': id_, 'randomNumber': r[0]}) 74 | return json_response(result) 75 | 76 | 77 | async def multiple_database_queries_raw(request): 78 | """ 79 | Test 3 RAW 80 | """ 81 | num_queries = get_num_queries(request) 82 | 83 | ids = [randint(1, 10000) for _ in range(num_queries)] 84 | ids.sort() 85 | 86 | result = [] 87 | async with request.app['pg_raw'].acquire() as conn: 88 | stmt = await conn.prepare('SELECT randomnumber FROM world WHERE id = $1') 89 | for id_ in ids: 90 | result.append({ 91 | 'id': id_, 92 | 'randomNumber': await stmt.fetchval(id_), 93 | }) 94 | return json_response(result) 95 | 96 | 97 | @template('fortune.jinja') 98 | async def fortunes(request): 99 | """ 100 | Test 4 ORM 101 | """ 102 | async with request.app['pg_orm'].acquire() as conn: 103 | cur = await conn.execute(select([sa_fortunes.c.id, sa_fortunes.c.message])) 104 | fortunes = list(await cur.fetchall()) 105 | fortunes.append(Fortune(id=0, message='Additional fortune added at request time.')) 106 | fortunes.sort(key=attrgetter('message')) 107 | return {'fortunes': fortunes} 108 | 109 | 110 | @template('fortune.jinja') 111 | async def fortunes_raw(request): 112 | """ 113 | Test 4 RAW 114 | """ 115 | async with request.app['pg_raw'].acquire() as conn: 116 | fortunes = await conn.fetch('SELECT * FROM Fortune') 117 | fortunes.append(dict(id=0, message='Additional fortune added at request time.')) 118 | fortunes.sort(key=itemgetter('message')) 119 | return {'fortunes': fortunes} 120 | 121 | 122 | async def updates(request): 123 | """ 124 | Test 5 ORM 125 | """ 126 | num_queries = get_num_queries(request) 127 | result = [] 128 | 129 | ids = [randint(1, 10000) for _ in range(num_queries)] 130 | ids.sort() 131 | 132 | async with request.app['pg_orm'].acquire() as conn: 133 | for id_ in ids: 134 | cur = await conn.execute( 135 | select([sa_worlds.c.randomnumber]) 136 | .where(sa_worlds.c.id == id_) 137 | ) 138 | # the result of this is a dict with the previous random number `randomnumber` which we don't actually use 139 | await cur.first() 140 | rand_new = randint(1, 10000) 141 | await conn.execute( 142 | sa_worlds.update() 143 | .where(sa_worlds.c.id == id_) 144 | .values(randomnumber=rand_new) 145 | ) 146 | result.append({'id': id_, 'randomNumber': rand_new}) 147 | return json_response(result) 148 | 149 | async def updates_raw(request): 150 | """ 151 | Test 5 RAW 152 | """ 153 | num_queries = get_num_queries(request) 154 | 155 | ids = [randint(1, 10000) for _ in range(num_queries)] 156 | ids.sort() 157 | 158 | result = [] 159 | updates = [] 160 | async with request.app['pg_raw'].acquire() as conn: 161 | stmt = await conn.prepare('SELECT randomnumber FROM world WHERE id = $1') 162 | for id_ in ids: 163 | # the result of this is the int previous random number which we don't actually use 164 | await stmt.fetchval(id_) 165 | rand_new = randint(1, 10000) 166 | result.append({'id': id_, 'randomNumber': rand_new}) 167 | updates.append((rand_new, id_)) 168 | await conn.executemany('UPDATE world SET randomnumber=$1 WHERE id=$2', updates) 169 | 170 | return json_response(result) 171 | 172 | 173 | async def plaintext(request): 174 | """ 175 | Test 6 176 | """ 177 | return Response(body=b'Hello, World!', content_type='text/plain') 178 | -------------------------------------------------------------------------------- /process.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import json 4 | from itertools import groupby 5 | from pathlib import Path 6 | 7 | with Path('results.json').open() as f: 8 | results = json.load(f) 9 | 10 | compare = os.getenv('COMPARE', 'aiohttp').lower() 11 | assert compare in ('python', 'aiohttp') 12 | 13 | not_compared = 'python' if compare == 'aiohttp' else 'aiohttp' 14 | grouping = not_compared, 'url', 'db', 'queries', 'concurrency' 15 | sort_on = grouping + (compare,) 16 | results.sort(key=lambda v: [v[g] for g in sort_on]) 17 | 18 | i = 0 19 | head = None 20 | url_previous = None 21 | for k, g in groupby(results, lambda v: [v[g] for g in grouping]): 22 | not_compared_version, url, db, queries, concurrency = k 23 | if url_previous and url_previous != url: 24 | print() 25 | url_previous = url 26 | if i == 0: 27 | head = f'{"URL":>18} {not_compared:>8} {"DB":>8} {"queries":>8} {"Conc":>8} ' 28 | line = f'{url:>18} {not_compared_version:>8} {db:>8} {queries:>8} {concurrency:>8} ' 29 | ref = None 30 | for j, data in enumerate(g): 31 | s = f'{data["request_rate"]:0,.0f}' 32 | if j == 0: 33 | if i == 0: 34 | head += f'{data[compare]:>10} ' 35 | 36 | ref = data["request_rate"] 37 | line += f'{s:>10} ' 38 | else: 39 | if i == 0: 40 | head += f'{data[compare]:>15} ' 41 | improvement = (data['request_rate'] - ref) / ref * 100 42 | s += f' |{improvement:3.0f}%' 43 | line += f'{s:>15} ' 44 | if i == 0: 45 | print(head) 46 | print(line) 47 | i += 1 48 | -------------------------------------------------------------------------------- /remote-setup/data.sql: -------------------------------------------------------------------------------- 1 | /* unchanged from FrameworkBenchmarks except user changed from benchmarkdbuser to postgres */ 2 | DROP TABLE IF EXISTS World; 3 | CREATE TABLE World ( 4 | id integer NOT NULL, 5 | randomNumber integer NOT NULL default 0, 6 | PRIMARY KEY (id) 7 | ); 8 | GRANT SELECT, UPDATE ON World to postgres; 9 | 10 | INSERT INTO World (id, randomnumber) 11 | SELECT x.id, random() * 10000 + 1 FROM generate_series(1,10000) as x(id); 12 | 13 | DROP TABLE IF EXISTS Fortune; 14 | CREATE TABLE Fortune ( 15 | id integer NOT NULL, 16 | message varchar(2048) NOT NULL, 17 | PRIMARY KEY (id) 18 | ); 19 | GRANT SELECT ON Fortune to postgres; 20 | 21 | INSERT INTO Fortune (id, message) VALUES (1, 'fortune: No such file or directory'); 22 | INSERT INTO Fortune (id, message) VALUES (2, 'A computer scientist is someone who fixes things that aren''t broken.'); 23 | INSERT INTO Fortune (id, message) VALUES (3, 'After enough decimal places, nobody gives a damn.'); 24 | INSERT INTO Fortune (id, message) VALUES (4, 'A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1'); 25 | INSERT INTO Fortune (id, message) VALUES (5, 'A computer program does what you tell it to do, not what you want it to do.'); 26 | INSERT INTO Fortune (id, message) VALUES (6, 'Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen'); 27 | INSERT INTO Fortune (id, message) VALUES (7, 'Any program that runs right is obsolete.'); 28 | INSERT INTO Fortune (id, message) VALUES (8, 'A list is only as strong as its weakest link. — Donald Knuth'); 29 | INSERT INTO Fortune (id, message) VALUES (9, 'Feature: A bug with seniority.'); 30 | INSERT INTO Fortune (id, message) VALUES (10, 'Computers make very fast, very accurate mistakes.'); 31 | INSERT INTO Fortune (id, message) VALUES (11, ''); 32 | INSERT INTO Fortune (id, message) VALUES (12, 'フレームワークのベンチマーク'); 33 | 34 | 35 | DROP TABLE IF EXISTS "World"; 36 | CREATE TABLE "World" ( 37 | id integer NOT NULL, 38 | randomNumber integer NOT NULL default 0, 39 | PRIMARY KEY (id) 40 | ); 41 | GRANT SELECT, UPDATE ON "World" to postgres; 42 | 43 | INSERT INTO "World" (id, randomnumber) 44 | SELECT x.id, random() * 10000 + 1 FROM generate_series(1,10000) as x(id); 45 | 46 | DROP TABLE IF EXISTS "Fortune"; 47 | CREATE TABLE "Fortune" ( 48 | id integer NOT NULL, 49 | message varchar(2048) NOT NULL, 50 | PRIMARY KEY (id) 51 | ); 52 | GRANT SELECT ON "Fortune" to postgres; 53 | 54 | INSERT INTO "Fortune" (id, message) VALUES (1, 'fortune: No such file or directory'); 55 | INSERT INTO "Fortune" (id, message) VALUES (2, 'A computer scientist is someone who fixes things that aren''t broken.'); 56 | INSERT INTO "Fortune" (id, message) VALUES (3, 'After enough decimal places, nobody gives a damn.'); 57 | INSERT INTO "Fortune" (id, message) VALUES (4, 'A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1'); 58 | INSERT INTO "Fortune" (id, message) VALUES (5, 'A computer program does what you tell it to do, not what you want it to do.'); 59 | INSERT INTO "Fortune" (id, message) VALUES (6, 'Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen'); 60 | INSERT INTO "Fortune" (id, message) VALUES (7, 'Any program that runs right is obsolete.'); 61 | INSERT INTO "Fortune" (id, message) VALUES (8, 'A list is only as strong as its weakest link. — Donald Knuth'); 62 | INSERT INTO "Fortune" (id, message) VALUES (9, 'Feature: A bug with seniority.'); 63 | INSERT INTO "Fortune" (id, message) VALUES (10, 'Computers make very fast, very accurate mistakes.'); 64 | INSERT INTO "Fortune" (id, message) VALUES (11, ''); 65 | INSERT INTO "Fortune" (id, message) VALUES (12, 'フレームワークのベンチマーク'); 66 | -------------------------------------------------------------------------------- /remote-setup/requirements.txt: -------------------------------------------------------------------------------- 1 | # packages required for all environments 2 | aiohttp-jinja2==1.4.2 3 | aiopg==1.1.0 4 | asyncpg==0.21.0 5 | cchardet==2.1.7 6 | psycopg2==2.8.6 7 | SQLAlchemy==1.3.22 8 | ujson==4.0.1 9 | uvloop==0.14.0 10 | -------------------------------------------------------------------------------- /remote-setup/serve.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import sys 3 | from pathlib import Path 4 | 5 | import uvloop 6 | from aiohttp import web 7 | 8 | if Path('/vagrant').exists(): 9 | d = '/vagrant' 10 | else: 11 | d = str(Path.home()) 12 | 13 | sys.path.append(str(d)) 14 | 15 | from app.main import create_app 16 | 17 | asyncio.get_event_loop().close() 18 | asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) 19 | app = create_app() 20 | web.run_app(app, port=80, print=lambda v: None, access_log=None) 21 | -------------------------------------------------------------------------------- /remote-setup/setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -x 4 | set -e 5 | sudo apt-get update 6 | 7 | sudo apt-get install -y software-properties-common 8 | 9 | sudo add-apt-repository ppa:deadsnakes/ppa -y 10 | sudo apt-get update 11 | sudo apt-get install -y postgresql-client postgresql postgresql-contrib postgresql-server-dev-all 12 | 13 | sudo apt-get install -y python3-pip python3-dev python3-psycopg2 virtualenv 14 | THIS_DIR=`dirname "$0"` 15 | 16 | for PYV in 7 8 9 17 | do 18 | sudo apt-get install -y python3.${PYV} python3.${PYV}-dev 19 | if [ ! -d ~/env3${PYV} ]; then 20 | virtualenv -p /usr/bin/python3.${PYV} ~/env3${PYV} 21 | fi 22 | ~/env3${PYV}/bin/python -m pip install -r ${THIS_DIR}/requirements.txt 23 | done 24 | 25 | export PGPASSWORD=benchmarks 26 | sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '$PGPASSWORD';" 27 | psql -h localhost -U postgres -c "DROP DATABASE IF EXISTS hello_world" 28 | psql -h localhost -U postgres -c "CREATE DATABASE hello_world" 29 | psql -h localhost -U postgres -d hello_world -f ${THIS_DIR}/data.sql 30 | 31 | cp ${THIS_DIR}/serve.py ~/ 32 | -------------------------------------------------------------------------------- /results.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "aiohttp": "3.6", 4 | "concurrency": 32, 5 | "db": "orm", 6 | "errors": 0, 7 | "latency": 27.84, 8 | "python": "3.7", 9 | "queries": "-", 10 | "request_rate": 1147.71, 11 | "timestamp": "2020-12-27 22:35:1609108542", 12 | "url": "/{c}/db" 13 | }, 14 | { 15 | "aiohttp": "3.6", 16 | "concurrency": 64, 17 | "db": "orm", 18 | "errors": 0, 19 | "latency": 57.7, 20 | "python": "3.7", 21 | "queries": "-", 22 | "request_rate": 1103.49, 23 | "timestamp": "2020-12-27 22:35:1609108553", 24 | "url": "/{c}/db" 25 | }, 26 | { 27 | "aiohttp": "3.6", 28 | "concurrency": 128, 29 | "db": "orm", 30 | "errors": 0, 31 | "latency": 116.12, 32 | "python": "3.7", 33 | "queries": "-", 34 | "request_rate": 1095.04, 35 | "timestamp": "2020-12-27 22:36:1609108565", 36 | "url": "/{c}/db" 37 | }, 38 | { 39 | "aiohttp": "3.6", 40 | "concurrency": 256, 41 | "db": "orm", 42 | "errors": 0, 43 | "latency": 237.8, 44 | "python": "3.7", 45 | "queries": "-", 46 | "request_rate": 1066.74, 47 | "timestamp": "2020-12-27 22:36:1609108577", 48 | "url": "/{c}/db" 49 | }, 50 | { 51 | "aiohttp": "3.6", 52 | "concurrency": 256, 53 | "db": "orm", 54 | "errors": 0, 55 | "latency": 736.77, 56 | "python": "3.7", 57 | "queries": 5, 58 | "request_rate": 330.1, 59 | "timestamp": "2020-12-27 22:36:1609108589", 60 | "url": "/{c}/queries/{q}" 61 | }, 62 | { 63 | "aiohttp": "3.6", 64 | "concurrency": 256, 65 | "db": "orm", 66 | "errors": 0, 67 | "latency": 1360.0, 68 | "python": "3.7", 69 | "queries": 10, 70 | "request_rate": 170.04, 71 | "timestamp": "2020-12-27 22:36:1609108601", 72 | "url": "/{c}/queries/{q}" 73 | }, 74 | { 75 | "aiohttp": "3.6", 76 | "concurrency": 256, 77 | "db": "orm", 78 | "errors": 1, 79 | "latency": 2570.0, 80 | "python": "3.7", 81 | "queries": 20, 82 | "request_rate": 85.05, 83 | "timestamp": "2020-12-27 22:36:1609108613", 84 | "url": "/{c}/queries/{q}" 85 | }, 86 | { 87 | "aiohttp": "3.6", 88 | "concurrency": 32, 89 | "db": "orm", 90 | "errors": 0, 91 | "latency": 36.08, 92 | "python": "3.7", 93 | "queries": "-", 94 | "request_rate": 884.54, 95 | "timestamp": "2020-12-27 22:37:1609108624", 96 | "url": "/{c}/fortunes" 97 | }, 98 | { 99 | "aiohttp": "3.6", 100 | "concurrency": 64, 101 | "db": "orm", 102 | "errors": 0, 103 | "latency": 71.24, 104 | "python": "3.7", 105 | "queries": "-", 106 | "request_rate": 893.26, 107 | "timestamp": "2020-12-27 22:37:1609108636", 108 | "url": "/{c}/fortunes" 109 | }, 110 | { 111 | "aiohttp": "3.6", 112 | "concurrency": 128, 113 | "db": "orm", 114 | "errors": 0, 115 | "latency": 146.7, 116 | "python": "3.7", 117 | "queries": "-", 118 | "request_rate": 865.63, 119 | "timestamp": "2020-12-27 22:37:1609108648", 120 | "url": "/{c}/fortunes" 121 | }, 122 | { 123 | "aiohttp": "3.6", 124 | "concurrency": 256, 125 | "db": "orm", 126 | "errors": 0, 127 | "latency": 288.61, 128 | "python": "3.7", 129 | "queries": "-", 130 | "request_rate": 864.09, 131 | "timestamp": "2020-12-27 22:37:1609108660", 132 | "url": "/{c}/fortunes" 133 | }, 134 | { 135 | "aiohttp": "3.6", 136 | "concurrency": 256, 137 | "db": "orm", 138 | "errors": 0, 139 | "latency": 1400.0, 140 | "python": "3.7", 141 | "queries": 5, 142 | "request_rate": 167.64, 143 | "timestamp": "2020-12-27 22:37:1609108671", 144 | "url": "/{c}/updates/{q}" 145 | }, 146 | { 147 | "aiohttp": "3.6", 148 | "concurrency": 256, 149 | "db": "orm", 150 | "errors": 0, 151 | "latency": 2270.0, 152 | "python": "3.7", 153 | "queries": 10, 154 | "request_rate": 95.96, 155 | "timestamp": "2020-12-27 22:38:1609108683", 156 | "url": "/{c}/updates/{q}" 157 | }, 158 | { 159 | "aiohttp": "3.6", 160 | "concurrency": 256, 161 | "db": "orm", 162 | "errors": 16, 163 | "latency": 3480.0, 164 | "python": "3.7", 165 | "queries": 20, 166 | "request_rate": 49.25, 167 | "timestamp": "2020-12-27 22:38:1609108695", 168 | "url": "/{c}/updates/{q}" 169 | }, 170 | { 171 | "aiohttp": "3.6", 172 | "concurrency": 32, 173 | "db": "-", 174 | "errors": 0, 175 | "latency": 4.5, 176 | "python": "3.7", 177 | "queries": "-", 178 | "request_rate": 7139.5, 179 | "timestamp": "2020-12-27 22:38:1609108707", 180 | "url": "/json" 181 | }, 182 | { 183 | "aiohttp": "3.6", 184 | "concurrency": 64, 185 | "db": "-", 186 | "errors": 0, 187 | "latency": 8.96, 188 | "python": "3.7", 189 | "queries": "-", 190 | "request_rate": 7142.53, 191 | "timestamp": "2020-12-27 22:38:1609108719", 192 | "url": "/json" 193 | }, 194 | { 195 | "aiohttp": "3.6", 196 | "concurrency": 128, 197 | "db": "-", 198 | "errors": 0, 199 | "latency": 16.86, 200 | "python": "3.7", 201 | "queries": "-", 202 | "request_rate": 7565.47, 203 | "timestamp": "2020-12-27 22:38:1609108730", 204 | "url": "/json" 205 | }, 206 | { 207 | "aiohttp": "3.6", 208 | "concurrency": 256, 209 | "db": "-", 210 | "errors": 0, 211 | "latency": 36.67, 212 | "python": "3.7", 213 | "queries": "-", 214 | "request_rate": 6937.56, 215 | "timestamp": "2020-12-27 22:39:1609108742", 216 | "url": "/json" 217 | }, 218 | { 219 | "aiohttp": "3.6", 220 | "concurrency": 32, 221 | "db": "-", 222 | "errors": 0, 223 | "latency": 4.56, 224 | "python": "3.7", 225 | "queries": "-", 226 | "request_rate": 7055.54, 227 | "timestamp": "2020-12-27 22:39:1609108754", 228 | "url": "/plaintext" 229 | }, 230 | { 231 | "aiohttp": "3.6", 232 | "concurrency": 64, 233 | "db": "-", 234 | "errors": 0, 235 | "latency": 9.21, 236 | "python": "3.7", 237 | "queries": "-", 238 | "request_rate": 6937.62, 239 | "timestamp": "2020-12-27 22:39:1609108766", 240 | "url": "/plaintext" 241 | }, 242 | { 243 | "aiohttp": "3.6", 244 | "concurrency": 128, 245 | "db": "-", 246 | "errors": 0, 247 | "latency": 19.91, 248 | "python": "3.7", 249 | "queries": "-", 250 | "request_rate": 6397.57, 251 | "timestamp": "2020-12-27 22:39:1609108778", 252 | "url": "/plaintext" 253 | }, 254 | { 255 | "aiohttp": "3.6", 256 | "concurrency": 256, 257 | "db": "-", 258 | "errors": 0, 259 | "latency": 36.41, 260 | "python": "3.7", 261 | "queries": "-", 262 | "request_rate": 6975.23, 263 | "timestamp": "2020-12-27 22:39:1609108790", 264 | "url": "/plaintext" 265 | }, 266 | { 267 | "aiohttp": "3.6", 268 | "concurrency": 32, 269 | "db": "raw", 270 | "errors": 0, 271 | "latency": 13.55, 272 | "python": "3.7", 273 | "queries": "-", 274 | "request_rate": 2460.22, 275 | "timestamp": "2020-12-27 22:40:1609108802", 276 | "url": "/{c}/db" 277 | }, 278 | { 279 | "aiohttp": "3.6", 280 | "concurrency": 64, 281 | "db": "raw", 282 | "errors": 0, 283 | "latency": 28.54, 284 | "python": "3.7", 285 | "queries": "-", 286 | "request_rate": 2339.39, 287 | "timestamp": "2020-12-27 22:40:1609108813", 288 | "url": "/{c}/db" 289 | }, 290 | { 291 | "aiohttp": "3.6", 292 | "concurrency": 128, 293 | "db": "raw", 294 | "errors": 0, 295 | "latency": 61.76, 296 | "python": "3.7", 297 | "queries": "-", 298 | "request_rate": 2494.36, 299 | "timestamp": "2020-12-27 22:40:1609108825", 300 | "url": "/{c}/db" 301 | }, 302 | { 303 | "aiohttp": "3.6", 304 | "concurrency": 256, 305 | "db": "raw", 306 | "errors": 0, 307 | "latency": 141.32, 308 | "python": "3.7", 309 | "queries": "-", 310 | "request_rate": 2318.04, 311 | "timestamp": "2020-12-27 22:40:1609108837", 312 | "url": "/{c}/db" 313 | }, 314 | { 315 | "aiohttp": "3.6", 316 | "concurrency": 256, 317 | "db": "raw", 318 | "errors": 0, 319 | "latency": 265.36, 320 | "python": "3.7", 321 | "queries": 5, 322 | "request_rate": 1090.98, 323 | "timestamp": "2020-12-27 22:40:1609108849", 324 | "url": "/{c}/queries/{q}" 325 | }, 326 | { 327 | "aiohttp": "3.6", 328 | "concurrency": 256, 329 | "db": "raw", 330 | "errors": 0, 331 | "latency": 335.85, 332 | "python": "3.7", 333 | "queries": 10, 334 | "request_rate": 814.52, 335 | "timestamp": "2020-12-27 22:41:1609108860", 336 | "url": "/{c}/queries/{q}" 337 | }, 338 | { 339 | "aiohttp": "3.6", 340 | "concurrency": 256, 341 | "db": "raw", 342 | "errors": 0, 343 | "latency": 454.93, 344 | "python": "3.7", 345 | "queries": 20, 346 | "request_rate": 571.1, 347 | "timestamp": "2020-12-27 22:41:1609108871", 348 | "url": "/{c}/queries/{q}" 349 | }, 350 | { 351 | "aiohttp": "3.6", 352 | "concurrency": 32, 353 | "db": "raw", 354 | "errors": 0, 355 | "latency": 20.21, 356 | "python": "3.7", 357 | "queries": "-", 358 | "request_rate": 1588.44, 359 | "timestamp": "2020-12-27 22:41:1609108882", 360 | "url": "/{c}/fortunes" 361 | }, 362 | { 363 | "aiohttp": "3.6", 364 | "concurrency": 64, 365 | "db": "raw", 366 | "errors": 0, 367 | "latency": 43.16, 368 | "python": "3.7", 369 | "queries": "-", 370 | "request_rate": 1559.3, 371 | "timestamp": "2020-12-27 22:41:1609108893", 372 | "url": "/{c}/fortunes" 373 | }, 374 | { 375 | "aiohttp": "3.6", 376 | "concurrency": 128, 377 | "db": "raw", 378 | "errors": 0, 379 | "latency": 100.81, 380 | "python": "3.7", 381 | "queries": "-", 382 | "request_rate": 1542.52, 383 | "timestamp": "2020-12-27 22:41:1609108905", 384 | "url": "/{c}/fortunes" 385 | }, 386 | { 387 | "aiohttp": "3.6", 388 | "concurrency": 256, 389 | "db": "raw", 390 | "errors": 0, 391 | "latency": 229.47, 392 | "python": "3.7", 393 | "queries": "-", 394 | "request_rate": 1474.42, 395 | "timestamp": "2020-12-27 22:41:1609108916", 396 | "url": "/{c}/fortunes" 397 | }, 398 | { 399 | "aiohttp": "3.6", 400 | "concurrency": 256, 401 | "db": "raw", 402 | "errors": 0, 403 | "latency": 354.3, 404 | "python": "3.7", 405 | "queries": 5, 406 | "request_rate": 724.37, 407 | "timestamp": "2020-12-27 22:42:1609108927", 408 | "url": "/{c}/updates/{q}" 409 | }, 410 | { 411 | "aiohttp": "3.6", 412 | "concurrency": 256, 413 | "db": "raw", 414 | "errors": 0, 415 | "latency": 521.34, 416 | "python": "3.7", 417 | "queries": 10, 418 | "request_rate": 478.34, 419 | "timestamp": "2020-12-27 22:42:1609108938", 420 | "url": "/{c}/updates/{q}" 421 | }, 422 | { 423 | "aiohttp": "3.6", 424 | "concurrency": 256, 425 | "db": "raw", 426 | "errors": 0, 427 | "latency": 880.29, 428 | "python": "3.7", 429 | "queries": 20, 430 | "request_rate": 276.87, 431 | "timestamp": "2020-12-27 22:42:1609108950", 432 | "url": "/{c}/updates/{q}" 433 | }, 434 | { 435 | "aiohttp": "3.7", 436 | "concurrency": 32, 437 | "db": "orm", 438 | "errors": 0, 439 | "latency": 28.43, 440 | "python": "3.7", 441 | "queries": "-", 442 | "request_rate": 1122.55, 443 | "timestamp": "2020-12-27 22:42:1609108963", 444 | "url": "/{c}/db" 445 | }, 446 | { 447 | "aiohttp": "3.7", 448 | "concurrency": 64, 449 | "db": "orm", 450 | "errors": 0, 451 | "latency": 55.39, 452 | "python": "3.7", 453 | "queries": "-", 454 | "request_rate": 1150.45, 455 | "timestamp": "2020-12-27 22:42:1609108974", 456 | "url": "/{c}/db" 457 | }, 458 | { 459 | "aiohttp": "3.7", 460 | "concurrency": 128, 461 | "db": "orm", 462 | "errors": 0, 463 | "latency": 110.96, 464 | "python": "3.7", 465 | "queries": "-", 466 | "request_rate": 1144.69, 467 | "timestamp": "2020-12-27 22:43:1609108985", 468 | "url": "/{c}/db" 469 | }, 470 | { 471 | "aiohttp": "3.7", 472 | "concurrency": 256, 473 | "db": "orm", 474 | "errors": 0, 475 | "latency": 229.39, 476 | "python": "3.7", 477 | "queries": "-", 478 | "request_rate": 1095.81, 479 | "timestamp": "2020-12-27 22:43:1609108996", 480 | "url": "/{c}/db" 481 | }, 482 | { 483 | "aiohttp": "3.7", 484 | "concurrency": 256, 485 | "db": "orm", 486 | "errors": 0, 487 | "latency": 722.15, 488 | "python": "3.7", 489 | "queries": 5, 490 | "request_rate": 329.95, 491 | "timestamp": "2020-12-27 22:43:1609109007", 492 | "url": "/{c}/queries/{q}" 493 | }, 494 | { 495 | "aiohttp": "3.7", 496 | "concurrency": 256, 497 | "db": "orm", 498 | "errors": 0, 499 | "latency": 1410.0, 500 | "python": "3.7", 501 | "queries": 10, 502 | "request_rate": 168.67, 503 | "timestamp": "2020-12-27 22:43:1609109019", 504 | "url": "/{c}/queries/{q}" 505 | }, 506 | { 507 | "aiohttp": "3.7", 508 | "concurrency": 256, 509 | "db": "orm", 510 | "errors": 3, 511 | "latency": 2640.0, 512 | "python": "3.7", 513 | "queries": 20, 514 | "request_rate": 82.12, 515 | "timestamp": "2020-12-27 22:43:1609109031", 516 | "url": "/{c}/queries/{q}" 517 | }, 518 | { 519 | "aiohttp": "3.7", 520 | "concurrency": 32, 521 | "db": "orm", 522 | "errors": 0, 523 | "latency": 35.48, 524 | "python": "3.7", 525 | "queries": "-", 526 | "request_rate": 899.25, 527 | "timestamp": "2020-12-27 22:44:1609109042", 528 | "url": "/{c}/fortunes" 529 | }, 530 | { 531 | "aiohttp": "3.7", 532 | "concurrency": 64, 533 | "db": "orm", 534 | "errors": 0, 535 | "latency": 73.83, 536 | "python": "3.7", 537 | "queries": "-", 538 | "request_rate": 861.71, 539 | "timestamp": "2020-12-27 22:44:1609109054", 540 | "url": "/{c}/fortunes" 541 | }, 542 | { 543 | "aiohttp": "3.7", 544 | "concurrency": 128, 545 | "db": "orm", 546 | "errors": 0, 547 | "latency": 142.29, 548 | "python": "3.7", 549 | "queries": "-", 550 | "request_rate": 891.43, 551 | "timestamp": "2020-12-27 22:44:1609109066", 552 | "url": "/{c}/fortunes" 553 | }, 554 | { 555 | "aiohttp": "3.7", 556 | "concurrency": 256, 557 | "db": "orm", 558 | "errors": 0, 559 | "latency": 299.01, 560 | "python": "3.7", 561 | "queries": "-", 562 | "request_rate": 837.11, 563 | "timestamp": "2020-12-27 22:44:1609109078", 564 | "url": "/{c}/fortunes" 565 | }, 566 | { 567 | "aiohttp": "3.7", 568 | "concurrency": 256, 569 | "db": "orm", 570 | "errors": 0, 571 | "latency": 1420.0, 572 | "python": "3.7", 573 | "queries": 5, 574 | "request_rate": 163.76, 575 | "timestamp": "2020-12-27 22:44:1609109090", 576 | "url": "/{c}/updates/{q}" 577 | }, 578 | { 579 | "aiohttp": "3.7", 580 | "concurrency": 256, 581 | "db": "orm", 582 | "errors": 2, 583 | "latency": 2580.0, 584 | "python": "3.7", 585 | "queries": 10, 586 | "request_rate": 83.48, 587 | "timestamp": "2020-12-27 22:45:1609109102", 588 | "url": "/{c}/updates/{q}" 589 | }, 590 | { 591 | "aiohttp": "3.7", 592 | "concurrency": 256, 593 | "db": "orm", 594 | "errors": 12, 595 | "latency": 3100.0, 596 | "python": "3.7", 597 | "queries": 20, 598 | "request_rate": 49.55, 599 | "timestamp": "2020-12-27 22:45:1609109114", 600 | "url": "/{c}/updates/{q}" 601 | }, 602 | { 603 | "aiohttp": "3.7", 604 | "concurrency": 32, 605 | "db": "-", 606 | "errors": 0, 607 | "latency": 4.79, 608 | "python": "3.7", 609 | "queries": "-", 610 | "request_rate": 6722.62, 611 | "timestamp": "2020-12-27 22:45:1609109125", 612 | "url": "/json" 613 | }, 614 | { 615 | "aiohttp": "3.7", 616 | "concurrency": 64, 617 | "db": "-", 618 | "errors": 0, 619 | "latency": 8.71, 620 | "python": "3.7", 621 | "queries": "-", 622 | "request_rate": 7335.0, 623 | "timestamp": "2020-12-27 22:45:1609109136", 624 | "url": "/json" 625 | }, 626 | { 627 | "aiohttp": "3.7", 628 | "concurrency": 128, 629 | "db": "-", 630 | "errors": 0, 631 | "latency": 21.62, 632 | "python": "3.7", 633 | "queries": "-", 634 | "request_rate": 5893.51, 635 | "timestamp": "2020-12-27 22:45:1609109147", 636 | "url": "/json" 637 | }, 638 | { 639 | "aiohttp": "3.7", 640 | "concurrency": 256, 641 | "db": "-", 642 | "errors": 0, 643 | "latency": 38.83, 644 | "python": "3.7", 645 | "queries": "-", 646 | "request_rate": 6538.06, 647 | "timestamp": "2020-12-27 22:45:1609109159", 648 | "url": "/json" 649 | }, 650 | { 651 | "aiohttp": "3.7", 652 | "concurrency": 32, 653 | "db": "-", 654 | "errors": 0, 655 | "latency": 4.82, 656 | "python": "3.7", 657 | "queries": "-", 658 | "request_rate": 6713.95, 659 | "timestamp": "2020-12-27 22:46:1609109171", 660 | "url": "/plaintext" 661 | }, 662 | { 663 | "aiohttp": "3.7", 664 | "concurrency": 64, 665 | "db": "-", 666 | "errors": 0, 667 | "latency": 9.34, 668 | "python": "3.7", 669 | "queries": "-", 670 | "request_rate": 6847.7, 671 | "timestamp": "2020-12-27 22:46:1609109183", 672 | "url": "/plaintext" 673 | }, 674 | { 675 | "aiohttp": "3.7", 676 | "concurrency": 128, 677 | "db": "-", 678 | "errors": 0, 679 | "latency": 21.25, 680 | "python": "3.7", 681 | "queries": "-", 682 | "request_rate": 5996.5, 683 | "timestamp": "2020-12-27 22:46:1609109194", 684 | "url": "/plaintext" 685 | }, 686 | { 687 | "aiohttp": "3.7", 688 | "concurrency": 256, 689 | "db": "-", 690 | "errors": 0, 691 | "latency": 39.5, 692 | "python": "3.7", 693 | "queries": "-", 694 | "request_rate": 6425.28, 695 | "timestamp": "2020-12-27 22:46:1609109206", 696 | "url": "/plaintext" 697 | }, 698 | { 699 | "aiohttp": "3.7", 700 | "concurrency": 32, 701 | "db": "raw", 702 | "errors": 0, 703 | "latency": 13.4, 704 | "python": "3.7", 705 | "queries": "-", 706 | "request_rate": 2407.0, 707 | "timestamp": "2020-12-27 22:46:1609109218", 708 | "url": "/{c}/db" 709 | }, 710 | { 711 | "aiohttp": "3.7", 712 | "concurrency": 64, 713 | "db": "raw", 714 | "errors": 0, 715 | "latency": 30.55, 716 | "python": "3.7", 717 | "queries": "-", 718 | "request_rate": 2310.16, 719 | "timestamp": "2020-12-27 22:47:1609109230", 720 | "url": "/{c}/db" 721 | }, 722 | { 723 | "aiohttp": "3.7", 724 | "concurrency": 128, 725 | "db": "raw", 726 | "errors": 0, 727 | "latency": 70.47, 728 | "python": "3.7", 729 | "queries": "-", 730 | "request_rate": 2299.56, 731 | "timestamp": "2020-12-27 22:47:1609109241", 732 | "url": "/{c}/db" 733 | }, 734 | { 735 | "aiohttp": "3.7", 736 | "concurrency": 256, 737 | "db": "raw", 738 | "errors": 0, 739 | "latency": 153.87, 740 | "python": "3.7", 741 | "queries": "-", 742 | "request_rate": 2298.21, 743 | "timestamp": "2020-12-27 22:47:1609109252", 744 | "url": "/{c}/db" 745 | }, 746 | { 747 | "aiohttp": "3.7", 748 | "concurrency": 256, 749 | "db": "raw", 750 | "errors": 0, 751 | "latency": 287.94, 752 | "python": "3.7", 753 | "queries": 5, 754 | "request_rate": 1089.7, 755 | "timestamp": "2020-12-27 22:47:1609109263", 756 | "url": "/{c}/queries/{q}" 757 | }, 758 | { 759 | "aiohttp": "3.7", 760 | "concurrency": 256, 761 | "db": "raw", 762 | "errors": 0, 763 | "latency": 318.46, 764 | "python": "3.7", 765 | "queries": 10, 766 | "request_rate": 875.8, 767 | "timestamp": "2020-12-27 22:47:1609109275", 768 | "url": "/{c}/queries/{q}" 769 | }, 770 | { 771 | "aiohttp": "3.7", 772 | "concurrency": 256, 773 | "db": "raw", 774 | "errors": 0, 775 | "latency": 425.84, 776 | "python": "3.7", 777 | "queries": 20, 778 | "request_rate": 610.8, 779 | "timestamp": "2020-12-27 22:48:1609109286", 780 | "url": "/{c}/queries/{q}" 781 | }, 782 | { 783 | "aiohttp": "3.7", 784 | "concurrency": 32, 785 | "db": "raw", 786 | "errors": 0, 787 | "latency": 20.28, 788 | "python": "3.7", 789 | "queries": "-", 790 | "request_rate": 1582.07, 791 | "timestamp": "2020-12-27 22:48:1609109297", 792 | "url": "/{c}/fortunes" 793 | }, 794 | { 795 | "aiohttp": "3.7", 796 | "concurrency": 64, 797 | "db": "raw", 798 | "errors": 0, 799 | "latency": 43.86, 800 | "python": "3.7", 801 | "queries": "-", 802 | "request_rate": 1548.55, 803 | "timestamp": "2020-12-27 22:48:1609109308", 804 | "url": "/{c}/fortunes" 805 | }, 806 | { 807 | "aiohttp": "3.7", 808 | "concurrency": 128, 809 | "db": "raw", 810 | "errors": 0, 811 | "latency": 100.95, 812 | "python": "3.7", 813 | "queries": "-", 814 | "request_rate": 1525.11, 815 | "timestamp": "2020-12-27 22:48:1609109319", 816 | "url": "/{c}/fortunes" 817 | }, 818 | { 819 | "aiohttp": "3.7", 820 | "concurrency": 256, 821 | "db": "raw", 822 | "errors": 0, 823 | "latency": 219.11, 824 | "python": "3.7", 825 | "queries": "-", 826 | "request_rate": 1554.81, 827 | "timestamp": "2020-12-27 22:48:1609109330", 828 | "url": "/{c}/fortunes" 829 | }, 830 | { 831 | "aiohttp": "3.7", 832 | "concurrency": 256, 833 | "db": "raw", 834 | "errors": 0, 835 | "latency": 342.09, 836 | "python": "3.7", 837 | "queries": 5, 838 | "request_rate": 778.65, 839 | "timestamp": "2020-12-27 22:49:1609109342", 840 | "url": "/{c}/updates/{q}" 841 | }, 842 | { 843 | "aiohttp": "3.7", 844 | "concurrency": 256, 845 | "db": "raw", 846 | "errors": 0, 847 | "latency": 505.21, 848 | "python": "3.7", 849 | "queries": 10, 850 | "request_rate": 492.92, 851 | "timestamp": "2020-12-27 22:49:1609109353", 852 | "url": "/{c}/updates/{q}" 853 | }, 854 | { 855 | "aiohttp": "3.7", 856 | "concurrency": 256, 857 | "db": "raw", 858 | "errors": 0, 859 | "latency": 781.96, 860 | "python": "3.7", 861 | "queries": 20, 862 | "request_rate": 311.54, 863 | "timestamp": "2020-12-27 22:49:1609109364", 864 | "url": "/{c}/updates/{q}" 865 | }, 866 | { 867 | "aiohttp": "3.6", 868 | "concurrency": 32, 869 | "db": "orm", 870 | "errors": 0, 871 | "latency": 24.99, 872 | "python": "3.8", 873 | "queries": "-", 874 | "request_rate": 1278.56, 875 | "timestamp": "2020-12-27 22:50:1609109400", 876 | "url": "/{c}/db" 877 | }, 878 | { 879 | "aiohttp": "3.6", 880 | "concurrency": 64, 881 | "db": "orm", 882 | "errors": 0, 883 | "latency": 49.47, 884 | "python": "3.8", 885 | "queries": "-", 886 | "request_rate": 1287.67, 887 | "timestamp": "2020-12-27 22:50:1609109411", 888 | "url": "/{c}/db" 889 | }, 890 | { 891 | "aiohttp": "3.6", 892 | "concurrency": 128, 893 | "db": "orm", 894 | "errors": 0, 895 | "latency": 103.11, 896 | "python": "3.8", 897 | "queries": "-", 898 | "request_rate": 1232.14, 899 | "timestamp": "2020-12-27 22:50:1609109422", 900 | "url": "/{c}/db" 901 | }, 902 | { 903 | "aiohttp": "3.6", 904 | "concurrency": 256, 905 | "db": "orm", 906 | "errors": 0, 907 | "latency": 207.1, 908 | "python": "3.8", 909 | "queries": "-", 910 | "request_rate": 1216.72, 911 | "timestamp": "2020-12-27 22:50:1609109433", 912 | "url": "/{c}/db" 913 | }, 914 | { 915 | "aiohttp": "3.6", 916 | "concurrency": 256, 917 | "db": "orm", 918 | "errors": 0, 919 | "latency": 623.88, 920 | "python": "3.8", 921 | "queries": 5, 922 | "request_rate": 401.05, 923 | "timestamp": "2020-12-27 22:50:1609109444", 924 | "url": "/{c}/queries/{q}" 925 | }, 926 | { 927 | "aiohttp": "3.6", 928 | "concurrency": 256, 929 | "db": "orm", 930 | "errors": 0, 931 | "latency": 1170.0, 932 | "python": "3.8", 933 | "queries": 10, 934 | "request_rate": 204.69, 935 | "timestamp": "2020-12-27 22:50:1609109456", 936 | "url": "/{c}/queries/{q}" 937 | }, 938 | { 939 | "aiohttp": "3.6", 940 | "concurrency": 256, 941 | "db": "orm", 942 | "errors": 0, 943 | "latency": 2240.0, 944 | "python": "3.8", 945 | "queries": 20, 946 | "request_rate": 98.45, 947 | "timestamp": "2020-12-27 22:51:1609109467", 948 | "url": "/{c}/queries/{q}" 949 | }, 950 | { 951 | "aiohttp": "3.6", 952 | "concurrency": 32, 953 | "db": "orm", 954 | "errors": 0, 955 | "latency": 30.47, 956 | "python": "3.8", 957 | "queries": "-", 958 | "request_rate": 1047.38, 959 | "timestamp": "2020-12-27 22:51:1609109479", 960 | "url": "/{c}/fortunes" 961 | }, 962 | { 963 | "aiohttp": "3.6", 964 | "concurrency": 64, 965 | "db": "orm", 966 | "errors": 0, 967 | "latency": 62.13, 968 | "python": "3.8", 969 | "queries": "-", 970 | "request_rate": 1025.05, 971 | "timestamp": "2020-12-27 22:51:1609109491", 972 | "url": "/{c}/fortunes" 973 | }, 974 | { 975 | "aiohttp": "3.6", 976 | "concurrency": 128, 977 | "db": "orm", 978 | "errors": 0, 979 | "latency": 130.22, 980 | "python": "3.8", 981 | "queries": "-", 982 | "request_rate": 969.49, 983 | "timestamp": "2020-12-27 22:51:1609109502", 984 | "url": "/{c}/fortunes" 985 | }, 986 | { 987 | "aiohttp": "3.6", 988 | "concurrency": 256, 989 | "db": "orm", 990 | "errors": 0, 991 | "latency": 257.08, 992 | "python": "3.8", 993 | "queries": "-", 994 | "request_rate": 973.73, 995 | "timestamp": "2020-12-27 22:51:1609109514", 996 | "url": "/{c}/fortunes" 997 | }, 998 | { 999 | "aiohttp": "3.6", 1000 | "concurrency": 256, 1001 | "db": "orm", 1002 | "errors": 0, 1003 | "latency": 1240.0, 1004 | "python": "3.8", 1005 | "queries": 5, 1006 | "request_rate": 194.35, 1007 | "timestamp": "2020-12-27 22:52:1609109526", 1008 | "url": "/{c}/updates/{q}" 1009 | }, 1010 | { 1011 | "aiohttp": "3.6", 1012 | "concurrency": 256, 1013 | "db": "orm", 1014 | "errors": 1, 1015 | "latency": 2200.0, 1016 | "python": "3.8", 1017 | "queries": 10, 1018 | "request_rate": 99.51, 1019 | "timestamp": "2020-12-27 22:52:1609109538", 1020 | "url": "/{c}/updates/{q}" 1021 | }, 1022 | { 1023 | "aiohttp": "3.6", 1024 | "concurrency": 256, 1025 | "db": "orm", 1026 | "errors": 7, 1027 | "latency": 3110.0, 1028 | "python": "3.8", 1029 | "queries": 20, 1030 | "request_rate": 55.45, 1031 | "timestamp": "2020-12-27 22:52:1609109550", 1032 | "url": "/{c}/updates/{q}" 1033 | }, 1034 | { 1035 | "aiohttp": "3.6", 1036 | "concurrency": 32, 1037 | "db": "-", 1038 | "errors": 0, 1039 | "latency": 3.81, 1040 | "python": "3.8", 1041 | "queries": "-", 1042 | "request_rate": 8557.64, 1043 | "timestamp": "2020-12-27 22:52:1609109561", 1044 | "url": "/json" 1045 | }, 1046 | { 1047 | "aiohttp": "3.6", 1048 | "concurrency": 64, 1049 | "db": "-", 1050 | "errors": 0, 1051 | "latency": 6.9, 1052 | "python": "3.8", 1053 | "queries": "-", 1054 | "request_rate": 9277.94, 1055 | "timestamp": "2020-12-27 22:52:1609109573", 1056 | "url": "/json" 1057 | }, 1058 | { 1059 | "aiohttp": "3.6", 1060 | "concurrency": 128, 1061 | "db": "-", 1062 | "errors": 0, 1063 | "latency": 15.83, 1064 | "python": "3.8", 1065 | "queries": "-", 1066 | "request_rate": 8045.32, 1067 | "timestamp": "2020-12-27 22:53:1609109585", 1068 | "url": "/json" 1069 | }, 1070 | { 1071 | "aiohttp": "3.6", 1072 | "concurrency": 256, 1073 | "db": "-", 1074 | "errors": 0, 1075 | "latency": 30.02, 1076 | "python": "3.8", 1077 | "queries": "-", 1078 | "request_rate": 8510.55, 1079 | "timestamp": "2020-12-27 22:53:1609109597", 1080 | "url": "/json" 1081 | }, 1082 | { 1083 | "aiohttp": "3.6", 1084 | "concurrency": 32, 1085 | "db": "-", 1086 | "errors": 0, 1087 | "latency": 4.4, 1088 | "python": "3.8", 1089 | "queries": "-", 1090 | "request_rate": 7305.64, 1091 | "timestamp": "2020-12-27 22:53:1609109609", 1092 | "url": "/plaintext" 1093 | }, 1094 | { 1095 | "aiohttp": "3.6", 1096 | "concurrency": 64, 1097 | "db": "-", 1098 | "errors": 0, 1099 | "latency": 8.15, 1100 | "python": "3.8", 1101 | "queries": "-", 1102 | "request_rate": 7840.43, 1103 | "timestamp": "2020-12-27 22:53:1609109620", 1104 | "url": "/plaintext" 1105 | }, 1106 | { 1107 | "aiohttp": "3.6", 1108 | "concurrency": 128, 1109 | "db": "-", 1110 | "errors": 0, 1111 | "latency": 14.78, 1112 | "python": "3.8", 1113 | "queries": "-", 1114 | "request_rate": 8648.64, 1115 | "timestamp": "2020-12-27 22:53:1609109632", 1116 | "url": "/plaintext" 1117 | }, 1118 | { 1119 | "aiohttp": "3.6", 1120 | "concurrency": 256, 1121 | "db": "-", 1122 | "errors": 0, 1123 | "latency": 28.85, 1124 | "python": "3.8", 1125 | "queries": "-", 1126 | "request_rate": 8820.04, 1127 | "timestamp": "2020-12-27 22:54:1609109644", 1128 | "url": "/plaintext" 1129 | }, 1130 | { 1131 | "aiohttp": "3.6", 1132 | "concurrency": 32, 1133 | "db": "raw", 1134 | "errors": 0, 1135 | "latency": 11.62, 1136 | "python": "3.8", 1137 | "queries": "-", 1138 | "request_rate": 2776.51, 1139 | "timestamp": "2020-12-27 22:54:1609109656", 1140 | "url": "/{c}/db" 1141 | }, 1142 | { 1143 | "aiohttp": "3.6", 1144 | "concurrency": 64, 1145 | "db": "raw", 1146 | "errors": 0, 1147 | "latency": 25.51, 1148 | "python": "3.8", 1149 | "queries": "-", 1150 | "request_rate": 2600.28, 1151 | "timestamp": "2020-12-27 22:54:1609109667", 1152 | "url": "/{c}/db" 1153 | }, 1154 | { 1155 | "aiohttp": "3.6", 1156 | "concurrency": 128, 1157 | "db": "raw", 1158 | "errors": 0, 1159 | "latency": 58.07, 1160 | "python": "3.8", 1161 | "queries": "-", 1162 | "request_rate": 2644.62, 1163 | "timestamp": "2020-12-27 22:54:1609109679", 1164 | "url": "/{c}/db" 1165 | }, 1166 | { 1167 | "aiohttp": "3.6", 1168 | "concurrency": 256, 1169 | "db": "raw", 1170 | "errors": 0, 1171 | "latency": 131.68, 1172 | "python": "3.8", 1173 | "queries": "-", 1174 | "request_rate": 2515.75, 1175 | "timestamp": "2020-12-27 22:54:1609109691", 1176 | "url": "/{c}/db" 1177 | }, 1178 | { 1179 | "aiohttp": "3.6", 1180 | "concurrency": 256, 1181 | "db": "raw", 1182 | "errors": 0, 1183 | "latency": 262.45, 1184 | "python": "3.8", 1185 | "queries": 5, 1186 | "request_rate": 1109.98, 1187 | "timestamp": "2020-12-27 22:55:1609109703", 1188 | "url": "/{c}/queries/{q}" 1189 | }, 1190 | { 1191 | "aiohttp": "3.6", 1192 | "concurrency": 256, 1193 | "db": "raw", 1194 | "errors": 0, 1195 | "latency": 322.45, 1196 | "python": "3.8", 1197 | "queries": 10, 1198 | "request_rate": 844.1, 1199 | "timestamp": "2020-12-27 22:55:1609109715", 1200 | "url": "/{c}/queries/{q}" 1201 | }, 1202 | { 1203 | "aiohttp": "3.6", 1204 | "concurrency": 256, 1205 | "db": "raw", 1206 | "errors": 0, 1207 | "latency": 439.97, 1208 | "python": "3.8", 1209 | "queries": 20, 1210 | "request_rate": 592.83, 1211 | "timestamp": "2020-12-27 22:55:1609109726", 1212 | "url": "/{c}/queries/{q}" 1213 | }, 1214 | { 1215 | "aiohttp": "3.6", 1216 | "concurrency": 32, 1217 | "db": "raw", 1218 | "errors": 0, 1219 | "latency": 18.01, 1220 | "python": "3.8", 1221 | "queries": "-", 1222 | "request_rate": 1781.1, 1223 | "timestamp": "2020-12-27 22:55:1609109738", 1224 | "url": "/{c}/fortunes" 1225 | }, 1226 | { 1227 | "aiohttp": "3.6", 1228 | "concurrency": 64, 1229 | "db": "raw", 1230 | "errors": 0, 1231 | "latency": 40.54, 1232 | "python": "3.8", 1233 | "queries": "-", 1234 | "request_rate": 1637.37, 1235 | "timestamp": "2020-12-27 22:55:1609109749", 1236 | "url": "/{c}/fortunes" 1237 | }, 1238 | { 1239 | "aiohttp": "3.6", 1240 | "concurrency": 128, 1241 | "db": "raw", 1242 | "errors": 0, 1243 | "latency": 89.74, 1244 | "python": "3.8", 1245 | "queries": "-", 1246 | "request_rate": 1687.86, 1247 | "timestamp": "2020-12-27 22:56:1609109760", 1248 | "url": "/{c}/fortunes" 1249 | }, 1250 | { 1251 | "aiohttp": "3.6", 1252 | "concurrency": 256, 1253 | "db": "raw", 1254 | "errors": 0, 1255 | "latency": 198.1, 1256 | "python": "3.8", 1257 | "queries": "-", 1258 | "request_rate": 1676.79, 1259 | "timestamp": "2020-12-27 22:56:1609109771", 1260 | "url": "/{c}/fortunes" 1261 | }, 1262 | { 1263 | "aiohttp": "3.6", 1264 | "concurrency": 256, 1265 | "db": "raw", 1266 | "errors": 0, 1267 | "latency": 326.33, 1268 | "python": "3.8", 1269 | "queries": 5, 1270 | "request_rate": 785.9, 1271 | "timestamp": "2020-12-27 22:56:1609109782", 1272 | "url": "/{c}/updates/{q}" 1273 | }, 1274 | { 1275 | "aiohttp": "3.6", 1276 | "concurrency": 256, 1277 | "db": "raw", 1278 | "errors": 0, 1279 | "latency": 482.94, 1280 | "python": "3.8", 1281 | "queries": 10, 1282 | "request_rate": 520.81, 1283 | "timestamp": "2020-12-27 22:56:1609109794", 1284 | "url": "/{c}/updates/{q}" 1285 | }, 1286 | { 1287 | "aiohttp": "3.6", 1288 | "concurrency": 256, 1289 | "db": "raw", 1290 | "errors": 0, 1291 | "latency": 783.86, 1292 | "python": "3.8", 1293 | "queries": 20, 1294 | "request_rate": 313.56, 1295 | "timestamp": "2020-12-27 22:56:1609109805", 1296 | "url": "/{c}/updates/{q}" 1297 | }, 1298 | { 1299 | "aiohttp": "3.7", 1300 | "concurrency": 32, 1301 | "db": "orm", 1302 | "errors": 0, 1303 | "latency": 23.48, 1304 | "python": "3.8", 1305 | "queries": "-", 1306 | "request_rate": 1359.96, 1307 | "timestamp": "2020-12-27 22:56:1609109818", 1308 | "url": "/{c}/db" 1309 | }, 1310 | { 1311 | "aiohttp": "3.7", 1312 | "concurrency": 64, 1313 | "db": "orm", 1314 | "errors": 0, 1315 | "latency": 49.66, 1316 | "python": "3.8", 1317 | "queries": "-", 1318 | "request_rate": 1282.94, 1319 | "timestamp": "2020-12-27 22:57:1609109829", 1320 | "url": "/{c}/db" 1321 | }, 1322 | { 1323 | "aiohttp": "3.7", 1324 | "concurrency": 128, 1325 | "db": "orm", 1326 | "errors": 0, 1327 | "latency": 102.22, 1328 | "python": "3.8", 1329 | "queries": "-", 1330 | "request_rate": 1240.44, 1331 | "timestamp": "2020-12-27 22:57:1609109840", 1332 | "url": "/{c}/db" 1333 | }, 1334 | { 1335 | "aiohttp": "3.7", 1336 | "concurrency": 256, 1337 | "db": "orm", 1338 | "errors": 0, 1339 | "latency": 196.73, 1340 | "python": "3.8", 1341 | "queries": "-", 1342 | "request_rate": 1266.67, 1343 | "timestamp": "2020-12-27 22:57:1609109851", 1344 | "url": "/{c}/db" 1345 | }, 1346 | { 1347 | "aiohttp": "3.7", 1348 | "concurrency": 256, 1349 | "db": "orm", 1350 | "errors": 0, 1351 | "latency": 619.36, 1352 | "python": "3.8", 1353 | "queries": 5, 1354 | "request_rate": 406.88, 1355 | "timestamp": "2020-12-27 22:57:1609109862", 1356 | "url": "/{c}/queries/{q}" 1357 | }, 1358 | { 1359 | "aiohttp": "3.7", 1360 | "concurrency": 256, 1361 | "db": "orm", 1362 | "errors": 0, 1363 | "latency": 1180.0, 1364 | "python": "3.8", 1365 | "queries": 10, 1366 | "request_rate": 198.14, 1367 | "timestamp": "2020-12-27 22:57:1609109874", 1368 | "url": "/{c}/queries/{q}" 1369 | }, 1370 | { 1371 | "aiohttp": "3.7", 1372 | "concurrency": 256, 1373 | "db": "orm", 1374 | "errors": 0, 1375 | "latency": 2220.0, 1376 | "python": "3.8", 1377 | "queries": 20, 1378 | "request_rate": 100.52, 1379 | "timestamp": "2020-12-27 22:58:1609109885", 1380 | "url": "/{c}/queries/{q}" 1381 | }, 1382 | { 1383 | "aiohttp": "3.7", 1384 | "concurrency": 32, 1385 | "db": "orm", 1386 | "errors": 0, 1387 | "latency": 30.41, 1388 | "python": "3.8", 1389 | "queries": "-", 1390 | "request_rate": 1050.98, 1391 | "timestamp": "2020-12-27 22:58:1609109896", 1392 | "url": "/{c}/fortunes" 1393 | }, 1394 | { 1395 | "aiohttp": "3.7", 1396 | "concurrency": 64, 1397 | "db": "orm", 1398 | "errors": 0, 1399 | "latency": 64.67, 1400 | "python": "3.8", 1401 | "queries": "-", 1402 | "request_rate": 984.58, 1403 | "timestamp": "2020-12-27 22:58:1609109908", 1404 | "url": "/{c}/fortunes" 1405 | }, 1406 | { 1407 | "aiohttp": "3.7", 1408 | "concurrency": 128, 1409 | "db": "orm", 1410 | "errors": 0, 1411 | "latency": 125.32, 1412 | "python": "3.8", 1413 | "queries": "-", 1414 | "request_rate": 1009.51, 1415 | "timestamp": "2020-12-27 22:58:1609109920", 1416 | "url": "/{c}/fortunes" 1417 | }, 1418 | { 1419 | "aiohttp": "3.7", 1420 | "concurrency": 256, 1421 | "db": "orm", 1422 | "errors": 0, 1423 | "latency": 248.9, 1424 | "python": "3.8", 1425 | "queries": "-", 1426 | "request_rate": 1014.56, 1427 | "timestamp": "2020-12-27 22:58:1609109932", 1428 | "url": "/{c}/fortunes" 1429 | }, 1430 | { 1431 | "aiohttp": "3.7", 1432 | "concurrency": 256, 1433 | "db": "orm", 1434 | "errors": 0, 1435 | "latency": 1200.0, 1436 | "python": "3.8", 1437 | "queries": 5, 1438 | "request_rate": 201.37, 1439 | "timestamp": "2020-12-27 22:59:1609109944", 1440 | "url": "/{c}/updates/{q}" 1441 | }, 1442 | { 1443 | "aiohttp": "3.7", 1444 | "concurrency": 256, 1445 | "db": "orm", 1446 | "errors": 0, 1447 | "latency": 2210.0, 1448 | "python": "3.8", 1449 | "queries": 10, 1450 | "request_rate": 102.45, 1451 | "timestamp": "2020-12-27 22:59:1609109955", 1452 | "url": "/{c}/updates/{q}" 1453 | }, 1454 | { 1455 | "aiohttp": "3.7", 1456 | "concurrency": 256, 1457 | "db": "orm", 1458 | "errors": 13, 1459 | "latency": 2800.0, 1460 | "python": "3.8", 1461 | "queries": 20, 1462 | "request_rate": 57.67, 1463 | "timestamp": "2020-12-27 22:59:1609109967", 1464 | "url": "/{c}/updates/{q}" 1465 | }, 1466 | { 1467 | "aiohttp": "3.7", 1468 | "concurrency": 32, 1469 | "db": "-", 1470 | "errors": 0, 1471 | "latency": 4.47, 1472 | "python": "3.8", 1473 | "queries": "-", 1474 | "request_rate": 7199.45, 1475 | "timestamp": "2020-12-27 22:59:1609109979", 1476 | "url": "/json" 1477 | }, 1478 | { 1479 | "aiohttp": "3.7", 1480 | "concurrency": 64, 1481 | "db": "-", 1482 | "errors": 0, 1483 | "latency": 7.43, 1484 | "python": "3.8", 1485 | "queries": "-", 1486 | "request_rate": 8626.48, 1487 | "timestamp": "2020-12-27 22:59:1609109991", 1488 | "url": "/json" 1489 | }, 1490 | { 1491 | "aiohttp": "3.7", 1492 | "concurrency": 128, 1493 | "db": "-", 1494 | "errors": 0, 1495 | "latency": 17.43, 1496 | "python": "3.8", 1497 | "queries": "-", 1498 | "request_rate": 7309.58, 1499 | "timestamp": "2020-12-27 23:00:1609110003", 1500 | "url": "/json" 1501 | }, 1502 | { 1503 | "aiohttp": "3.7", 1504 | "concurrency": 256, 1505 | "db": "-", 1506 | "errors": 0, 1507 | "latency": 33.98, 1508 | "python": "3.8", 1509 | "queries": "-", 1510 | "request_rate": 7472.39, 1511 | "timestamp": "2020-12-27 23:00:1609110015", 1512 | "url": "/json" 1513 | }, 1514 | { 1515 | "aiohttp": "3.7", 1516 | "concurrency": 32, 1517 | "db": "-", 1518 | "errors": 0, 1519 | "latency": 4.53, 1520 | "python": "3.8", 1521 | "queries": "-", 1522 | "request_rate": 7151.22, 1523 | "timestamp": "2020-12-27 23:00:1609110026", 1524 | "url": "/plaintext" 1525 | }, 1526 | { 1527 | "aiohttp": "3.7", 1528 | "concurrency": 64, 1529 | "db": "-", 1530 | "errors": 0, 1531 | "latency": 6.95, 1532 | "python": "3.8", 1533 | "queries": "-", 1534 | "request_rate": 9218.85, 1535 | "timestamp": "2020-12-27 23:00:1609110038", 1536 | "url": "/plaintext" 1537 | }, 1538 | { 1539 | "aiohttp": "3.7", 1540 | "concurrency": 128, 1541 | "db": "-", 1542 | "errors": 0, 1543 | "latency": 13.36, 1544 | "python": "3.8", 1545 | "queries": "-", 1546 | "request_rate": 9535.83, 1547 | "timestamp": "2020-12-27 23:00:1609110050", 1548 | "url": "/plaintext" 1549 | }, 1550 | { 1551 | "aiohttp": "3.7", 1552 | "concurrency": 256, 1553 | "db": "-", 1554 | "errors": 0, 1555 | "latency": 28.88, 1556 | "python": "3.8", 1557 | "queries": "-", 1558 | "request_rate": 8794.58, 1559 | "timestamp": "2020-12-27 23:01:1609110062", 1560 | "url": "/plaintext" 1561 | }, 1562 | { 1563 | "aiohttp": "3.7", 1564 | "concurrency": 32, 1565 | "db": "raw", 1566 | "errors": 0, 1567 | "latency": 11.59, 1568 | "python": "3.8", 1569 | "queries": "-", 1570 | "request_rate": 2781.01, 1571 | "timestamp": "2020-12-27 23:01:1609110074", 1572 | "url": "/{c}/db" 1573 | }, 1574 | { 1575 | "aiohttp": "3.7", 1576 | "concurrency": 64, 1577 | "db": "raw", 1578 | "errors": 0, 1579 | "latency": 26.4, 1580 | "python": "3.8", 1581 | "queries": "-", 1582 | "request_rate": 2667.79, 1583 | "timestamp": "2020-12-27 23:01:1609110085", 1584 | "url": "/{c}/db" 1585 | }, 1586 | { 1587 | "aiohttp": "3.7", 1588 | "concurrency": 128, 1589 | "db": "raw", 1590 | "errors": 0, 1591 | "latency": 61.31, 1592 | "python": "3.8", 1593 | "queries": "-", 1594 | "request_rate": 2751.03, 1595 | "timestamp": "2020-12-27 23:01:1609110097", 1596 | "url": "/{c}/db" 1597 | }, 1598 | { 1599 | "aiohttp": "3.7", 1600 | "concurrency": 256, 1601 | "db": "raw", 1602 | "errors": 0, 1603 | "latency": 143.6, 1604 | "python": "3.8", 1605 | "queries": "-", 1606 | "request_rate": 2565.18, 1607 | "timestamp": "2020-12-27 23:01:1609110108", 1608 | "url": "/{c}/db" 1609 | }, 1610 | { 1611 | "aiohttp": "3.7", 1612 | "concurrency": 256, 1613 | "db": "raw", 1614 | "errors": 0, 1615 | "latency": 262.64, 1616 | "python": "3.8", 1617 | "queries": 5, 1618 | "request_rate": 1191.06, 1619 | "timestamp": "2020-12-27 23:01:1609110119", 1620 | "url": "/{c}/queries/{q}" 1621 | }, 1622 | { 1623 | "aiohttp": "3.7", 1624 | "concurrency": 256, 1625 | "db": "raw", 1626 | "errors": 0, 1627 | "latency": 346.96, 1628 | "python": "3.8", 1629 | "queries": 10, 1630 | "request_rate": 847.24, 1631 | "timestamp": "2020-12-27 23:02:1609110131", 1632 | "url": "/{c}/queries/{q}" 1633 | }, 1634 | { 1635 | "aiohttp": "3.7", 1636 | "concurrency": 256, 1637 | "db": "raw", 1638 | "errors": 0, 1639 | "latency": 446.36, 1640 | "python": "3.8", 1641 | "queries": 20, 1642 | "request_rate": 595.57, 1643 | "timestamp": "2020-12-27 23:02:1609110142", 1644 | "url": "/{c}/queries/{q}" 1645 | }, 1646 | { 1647 | "aiohttp": "3.7", 1648 | "concurrency": 32, 1649 | "db": "raw", 1650 | "errors": 0, 1651 | "latency": 18.23, 1652 | "python": "3.8", 1653 | "queries": "-", 1654 | "request_rate": 1758.63, 1655 | "timestamp": "2020-12-27 23:02:1609110153", 1656 | "url": "/{c}/fortunes" 1657 | }, 1658 | { 1659 | "aiohttp": "3.7", 1660 | "concurrency": 64, 1661 | "db": "raw", 1662 | "errors": 0, 1663 | "latency": 39.63, 1664 | "python": "3.8", 1665 | "queries": "-", 1666 | "request_rate": 1714.21, 1667 | "timestamp": "2020-12-27 23:02:1609110164", 1668 | "url": "/{c}/fortunes" 1669 | }, 1670 | { 1671 | "aiohttp": "3.7", 1672 | "concurrency": 128, 1673 | "db": "raw", 1674 | "errors": 0, 1675 | "latency": 88.53, 1676 | "python": "3.8", 1677 | "queries": "-", 1678 | "request_rate": 1771.21, 1679 | "timestamp": "2020-12-27 23:02:1609110175", 1680 | "url": "/{c}/fortunes" 1681 | }, 1682 | { 1683 | "aiohttp": "3.7", 1684 | "concurrency": 256, 1685 | "db": "raw", 1686 | "errors": 0, 1687 | "latency": 205.62, 1688 | "python": "3.8", 1689 | "queries": "-", 1690 | "request_rate": 1646.85, 1691 | "timestamp": "2020-12-27 23:03:1609110186", 1692 | "url": "/{c}/fortunes" 1693 | }, 1694 | { 1695 | "aiohttp": "3.7", 1696 | "concurrency": 256, 1697 | "db": "raw", 1698 | "errors": 0, 1699 | "latency": 333.73, 1700 | "python": "3.8", 1701 | "queries": 5, 1702 | "request_rate": 776.71, 1703 | "timestamp": "2020-12-27 23:03:1609110198", 1704 | "url": "/{c}/updates/{q}" 1705 | }, 1706 | { 1707 | "aiohttp": "3.7", 1708 | "concurrency": 256, 1709 | "db": "raw", 1710 | "errors": 0, 1711 | "latency": 479.19, 1712 | "python": "3.8", 1713 | "queries": 10, 1714 | "request_rate": 523.3, 1715 | "timestamp": "2020-12-27 23:03:1609110209", 1716 | "url": "/{c}/updates/{q}" 1717 | }, 1718 | { 1719 | "aiohttp": "3.7", 1720 | "concurrency": 256, 1721 | "db": "raw", 1722 | "errors": 0, 1723 | "latency": 778.43, 1724 | "python": "3.8", 1725 | "queries": 20, 1726 | "request_rate": 314.27, 1727 | "timestamp": "2020-12-27 23:03:1609110220", 1728 | "url": "/{c}/updates/{q}" 1729 | }, 1730 | { 1731 | "aiohttp": "3.6", 1732 | "concurrency": 32, 1733 | "db": "orm", 1734 | "errors": 0, 1735 | "latency": 24.36, 1736 | "python": "3.9", 1737 | "queries": "-", 1738 | "request_rate": 1311.39, 1739 | "timestamp": "2020-12-27 23:04:1609110269", 1740 | "url": "/{c}/db" 1741 | }, 1742 | { 1743 | "aiohttp": "3.6", 1744 | "concurrency": 64, 1745 | "db": "orm", 1746 | "errors": 0, 1747 | "latency": 48.48, 1748 | "python": "3.9", 1749 | "queries": "-", 1750 | "request_rate": 1314.57, 1751 | "timestamp": "2020-12-27 23:04:1609110280", 1752 | "url": "/{c}/db" 1753 | }, 1754 | { 1755 | "aiohttp": "3.6", 1756 | "concurrency": 128, 1757 | "db": "orm", 1758 | "errors": 0, 1759 | "latency": 102.59, 1760 | "python": "3.9", 1761 | "queries": "-", 1762 | "request_rate": 1236.07, 1763 | "timestamp": "2020-12-27 23:04:1609110292", 1764 | "url": "/{c}/db" 1765 | }, 1766 | { 1767 | "aiohttp": "3.6", 1768 | "concurrency": 256, 1769 | "db": "orm", 1770 | "errors": 0, 1771 | "latency": 194.1, 1772 | "python": "3.9", 1773 | "queries": "-", 1774 | "request_rate": 1296.74, 1775 | "timestamp": "2020-12-27 23:05:1609110303", 1776 | "url": "/{c}/db" 1777 | }, 1778 | { 1779 | "aiohttp": "3.6", 1780 | "concurrency": 256, 1781 | "db": "orm", 1782 | "errors": 0, 1783 | "latency": 626.56, 1784 | "python": "3.9", 1785 | "queries": 5, 1786 | "request_rate": 392.82, 1787 | "timestamp": "2020-12-27 23:05:1609110314", 1788 | "url": "/{c}/queries/{q}" 1789 | }, 1790 | { 1791 | "aiohttp": "3.6", 1792 | "concurrency": 256, 1793 | "db": "orm", 1794 | "errors": 0, 1795 | "latency": 1210.0, 1796 | "python": "3.9", 1797 | "queries": 10, 1798 | "request_rate": 194.11, 1799 | "timestamp": "2020-12-27 23:05:1609110325", 1800 | "url": "/{c}/queries/{q}" 1801 | }, 1802 | { 1803 | "aiohttp": "3.6", 1804 | "concurrency": 256, 1805 | "db": "orm", 1806 | "errors": 0, 1807 | "latency": 2310.0, 1808 | "python": "3.9", 1809 | "queries": 20, 1810 | "request_rate": 96.45, 1811 | "timestamp": "2020-12-27 23:05:1609110337", 1812 | "url": "/{c}/queries/{q}" 1813 | }, 1814 | { 1815 | "aiohttp": "3.6", 1816 | "concurrency": 32, 1817 | "db": "orm", 1818 | "errors": 0, 1819 | "latency": 32.11, 1820 | "python": "3.9", 1821 | "queries": "-", 1822 | "request_rate": 995.07, 1823 | "timestamp": "2020-12-27 23:05:1609110348", 1824 | "url": "/{c}/fortunes" 1825 | }, 1826 | { 1827 | "aiohttp": "3.6", 1828 | "concurrency": 64, 1829 | "db": "orm", 1830 | "errors": 0, 1831 | "latency": 62.62, 1832 | "python": "3.9", 1833 | "queries": "-", 1834 | "request_rate": 1015.67, 1835 | "timestamp": "2020-12-27 23:06:1609110360", 1836 | "url": "/{c}/fortunes" 1837 | }, 1838 | { 1839 | "aiohttp": "3.6", 1840 | "concurrency": 128, 1841 | "db": "orm", 1842 | "errors": 0, 1843 | "latency": 122.27, 1844 | "python": "3.9", 1845 | "queries": "-", 1846 | "request_rate": 1034.63, 1847 | "timestamp": "2020-12-27 23:06:1609110371", 1848 | "url": "/{c}/fortunes" 1849 | }, 1850 | { 1851 | "aiohttp": "3.6", 1852 | "concurrency": 256, 1853 | "db": "orm", 1854 | "errors": 0, 1855 | "latency": 249.94, 1856 | "python": "3.9", 1857 | "queries": "-", 1858 | "request_rate": 1006.71, 1859 | "timestamp": "2020-12-27 23:06:1609110383", 1860 | "url": "/{c}/fortunes" 1861 | }, 1862 | { 1863 | "aiohttp": "3.6", 1864 | "concurrency": 256, 1865 | "db": "orm", 1866 | "errors": 0, 1867 | "latency": 1140.0, 1868 | "python": "3.9", 1869 | "queries": 5, 1870 | "request_rate": 213.79, 1871 | "timestamp": "2020-12-27 23:06:1609110395", 1872 | "url": "/{c}/updates/{q}" 1873 | }, 1874 | { 1875 | "aiohttp": "3.6", 1876 | "concurrency": 256, 1877 | "db": "orm", 1878 | "errors": 1, 1879 | "latency": 2170.0, 1880 | "python": "3.9", 1881 | "queries": 10, 1882 | "request_rate": 104.45, 1883 | "timestamp": "2020-12-27 23:06:1609110407", 1884 | "url": "/{c}/updates/{q}" 1885 | }, 1886 | { 1887 | "aiohttp": "3.6", 1888 | "concurrency": 256, 1889 | "db": "orm", 1890 | "errors": 9, 1891 | "latency": 3140.0, 1892 | "python": "3.9", 1893 | "queries": 20, 1894 | "request_rate": 57.55, 1895 | "timestamp": "2020-12-27 23:06:1609110419", 1896 | "url": "/{c}/updates/{q}" 1897 | }, 1898 | { 1899 | "aiohttp": "3.6", 1900 | "concurrency": 32, 1901 | "db": "-", 1902 | "errors": 0, 1903 | "latency": 3.78, 1904 | "python": "3.9", 1905 | "queries": "-", 1906 | "request_rate": 8615.5, 1907 | "timestamp": "2020-12-27 23:07:1609110430", 1908 | "url": "/json" 1909 | }, 1910 | { 1911 | "aiohttp": "3.6", 1912 | "concurrency": 64, 1913 | "db": "-", 1914 | "errors": 0, 1915 | "latency": 7.56, 1916 | "python": "3.9", 1917 | "queries": "-", 1918 | "request_rate": 8466.31, 1919 | "timestamp": "2020-12-27 23:07:1609110442", 1920 | "url": "/json" 1921 | }, 1922 | { 1923 | "aiohttp": "3.6", 1924 | "concurrency": 128, 1925 | "db": "-", 1926 | "errors": 0, 1927 | "latency": 13.2, 1928 | "python": "3.9", 1929 | "queries": "-", 1930 | "request_rate": 9669.51, 1931 | "timestamp": "2020-12-27 23:07:1609110454", 1932 | "url": "/json" 1933 | }, 1934 | { 1935 | "aiohttp": "3.6", 1936 | "concurrency": 256, 1937 | "db": "-", 1938 | "errors": 0, 1939 | "latency": 33.07, 1940 | "python": "3.9", 1941 | "queries": "-", 1942 | "request_rate": 7684.84, 1943 | "timestamp": "2020-12-27 23:07:1609110466", 1944 | "url": "/json" 1945 | }, 1946 | { 1947 | "aiohttp": "3.6", 1948 | "concurrency": 32, 1949 | "db": "-", 1950 | "errors": 0, 1951 | "latency": 3.66, 1952 | "python": "3.9", 1953 | "queries": "-", 1954 | "request_rate": 9364.67, 1955 | "timestamp": "2020-12-27 23:07:1609110477", 1956 | "url": "/plaintext" 1957 | }, 1958 | { 1959 | "aiohttp": "3.6", 1960 | "concurrency": 64, 1961 | "db": "-", 1962 | "errors": 0, 1963 | "latency": 6.37, 1964 | "python": "3.9", 1965 | "queries": "-", 1966 | "request_rate": 10148.09, 1967 | "timestamp": "2020-12-27 23:08:1609110489", 1968 | "url": "/plaintext" 1969 | }, 1970 | { 1971 | "aiohttp": "3.6", 1972 | "concurrency": 128, 1973 | "db": "-", 1974 | "errors": 0, 1975 | "latency": 12.67, 1976 | "python": "3.9", 1977 | "queries": "-", 1978 | "request_rate": 10091.11, 1979 | "timestamp": "2020-12-27 23:08:1609110500", 1980 | "url": "/plaintext" 1981 | }, 1982 | { 1983 | "aiohttp": "3.6", 1984 | "concurrency": 256, 1985 | "db": "-", 1986 | "errors": 0, 1987 | "latency": 30.87, 1988 | "python": "3.9", 1989 | "queries": "-", 1990 | "request_rate": 8262.71, 1991 | "timestamp": "2020-12-27 23:08:1609110512", 1992 | "url": "/plaintext" 1993 | }, 1994 | { 1995 | "aiohttp": "3.6", 1996 | "concurrency": 32, 1997 | "db": "raw", 1998 | "errors": 0, 1999 | "latency": 11.58, 2000 | "python": "3.9", 2001 | "queries": "-", 2002 | "request_rate": 2798.58, 2003 | "timestamp": "2020-12-27 23:08:1609110524", 2004 | "url": "/{c}/db" 2005 | }, 2006 | { 2007 | "aiohttp": "3.6", 2008 | "concurrency": 64, 2009 | "db": "raw", 2010 | "errors": 0, 2011 | "latency": 24.72, 2012 | "python": "3.9", 2013 | "queries": "-", 2014 | "request_rate": 2713.1, 2015 | "timestamp": "2020-12-27 23:08:1609110535", 2016 | "url": "/{c}/db" 2017 | }, 2018 | { 2019 | "aiohttp": "3.6", 2020 | "concurrency": 128, 2021 | "db": "raw", 2022 | "errors": 0, 2023 | "latency": 59.72, 2024 | "python": "3.9", 2025 | "queries": "-", 2026 | "request_rate": 2530.15, 2027 | "timestamp": "2020-12-27 23:09:1609110547", 2028 | "url": "/{c}/db" 2029 | }, 2030 | { 2031 | "aiohttp": "3.6", 2032 | "concurrency": 256, 2033 | "db": "raw", 2034 | "errors": 0, 2035 | "latency": 126.95, 2036 | "python": "3.9", 2037 | "queries": "-", 2038 | "request_rate": 2573.06, 2039 | "timestamp": "2020-12-27 23:09:1609110558", 2040 | "url": "/{c}/db" 2041 | }, 2042 | { 2043 | "aiohttp": "3.6", 2044 | "concurrency": 256, 2045 | "db": "raw", 2046 | "errors": 0, 2047 | "latency": 258.18, 2048 | "python": "3.9", 2049 | "queries": 5, 2050 | "request_rate": 1102.09, 2051 | "timestamp": "2020-12-27 23:09:1609110570", 2052 | "url": "/{c}/queries/{q}" 2053 | }, 2054 | { 2055 | "aiohttp": "3.6", 2056 | "concurrency": 256, 2057 | "db": "raw", 2058 | "errors": 0, 2059 | "latency": 309.07, 2060 | "python": "3.9", 2061 | "queries": 10, 2062 | "request_rate": 871.19, 2063 | "timestamp": "2020-12-27 23:09:1609110581", 2064 | "url": "/{c}/queries/{q}" 2065 | }, 2066 | { 2067 | "aiohttp": "3.6", 2068 | "concurrency": 256, 2069 | "db": "raw", 2070 | "errors": 0, 2071 | "latency": 456.68, 2072 | "python": "3.9", 2073 | "queries": 20, 2074 | "request_rate": 572.29, 2075 | "timestamp": "2020-12-27 23:09:1609110593", 2076 | "url": "/{c}/queries/{q}" 2077 | }, 2078 | { 2079 | "aiohttp": "3.6", 2080 | "concurrency": 32, 2081 | "db": "raw", 2082 | "errors": 0, 2083 | "latency": 18.6, 2084 | "python": "3.9", 2085 | "queries": "-", 2086 | "request_rate": 1727.19, 2087 | "timestamp": "2020-12-27 23:10:1609110604", 2088 | "url": "/{c}/fortunes" 2089 | }, 2090 | { 2091 | "aiohttp": "3.6", 2092 | "concurrency": 64, 2093 | "db": "raw", 2094 | "errors": 0, 2095 | "latency": 40.0, 2096 | "python": "3.9", 2097 | "queries": "-", 2098 | "request_rate": 1672.25, 2099 | "timestamp": "2020-12-27 23:10:1609110615", 2100 | "url": "/{c}/fortunes" 2101 | }, 2102 | { 2103 | "aiohttp": "3.6", 2104 | "concurrency": 128, 2105 | "db": "raw", 2106 | "errors": 0, 2107 | "latency": 89.51, 2108 | "python": "3.9", 2109 | "queries": "-", 2110 | "request_rate": 1618.71, 2111 | "timestamp": "2020-12-27 23:10:1609110626", 2112 | "url": "/{c}/fortunes" 2113 | }, 2114 | { 2115 | "aiohttp": "3.6", 2116 | "concurrency": 256, 2117 | "db": "raw", 2118 | "errors": 0, 2119 | "latency": 202.95, 2120 | "python": "3.9", 2121 | "queries": "-", 2122 | "request_rate": 1580.78, 2123 | "timestamp": "2020-12-27 23:10:1609110638", 2124 | "url": "/{c}/fortunes" 2125 | }, 2126 | { 2127 | "aiohttp": "3.6", 2128 | "concurrency": 256, 2129 | "db": "raw", 2130 | "errors": 0, 2131 | "latency": 348.94, 2132 | "python": "3.9", 2133 | "queries": 5, 2134 | "request_rate": 743.9, 2135 | "timestamp": "2020-12-27 23:10:1609110649", 2136 | "url": "/{c}/updates/{q}" 2137 | }, 2138 | { 2139 | "aiohttp": "3.6", 2140 | "concurrency": 256, 2141 | "db": "raw", 2142 | "errors": 0, 2143 | "latency": 505.71, 2144 | "python": "3.9", 2145 | "queries": 10, 2146 | "request_rate": 497.45, 2147 | "timestamp": "2020-12-27 23:11:1609110660", 2148 | "url": "/{c}/updates/{q}" 2149 | }, 2150 | { 2151 | "aiohttp": "3.6", 2152 | "concurrency": 256, 2153 | "db": "raw", 2154 | "errors": 0, 2155 | "latency": 801.07, 2156 | "python": "3.9", 2157 | "queries": 20, 2158 | "request_rate": 305.87, 2159 | "timestamp": "2020-12-27 23:11:1609110672", 2160 | "url": "/{c}/updates/{q}" 2161 | }, 2162 | { 2163 | "aiohttp": "3.7", 2164 | "concurrency": 32, 2165 | "db": "orm", 2166 | "errors": 0, 2167 | "latency": 23.72, 2168 | "python": "3.9", 2169 | "queries": "-", 2170 | "request_rate": 1348.2, 2171 | "timestamp": "2020-12-27 23:11:1609110685", 2172 | "url": "/{c}/db" 2173 | }, 2174 | { 2175 | "aiohttp": "3.7", 2176 | "concurrency": 64, 2177 | "db": "orm", 2178 | "errors": 0, 2179 | "latency": 50.45, 2180 | "python": "3.9", 2181 | "queries": "-", 2182 | "request_rate": 1263.48, 2183 | "timestamp": "2020-12-27 23:11:1609110696", 2184 | "url": "/{c}/db" 2185 | }, 2186 | { 2187 | "aiohttp": "3.7", 2188 | "concurrency": 128, 2189 | "db": "orm", 2190 | "errors": 0, 2191 | "latency": 96.79, 2192 | "python": "3.9", 2193 | "queries": "-", 2194 | "request_rate": 1312.15, 2195 | "timestamp": "2020-12-27 23:11:1609110707", 2196 | "url": "/{c}/db" 2197 | }, 2198 | { 2199 | "aiohttp": "3.7", 2200 | "concurrency": 256, 2201 | "db": "orm", 2202 | "errors": 0, 2203 | "latency": 196.11, 2204 | "python": "3.9", 2205 | "queries": "-", 2206 | "request_rate": 1290.81, 2207 | "timestamp": "2020-12-27 23:11:1609110718", 2208 | "url": "/{c}/db" 2209 | }, 2210 | { 2211 | "aiohttp": "3.7", 2212 | "concurrency": 256, 2213 | "db": "orm", 2214 | "errors": 0, 2215 | "latency": 639.19, 2216 | "python": "3.9", 2217 | "queries": 5, 2218 | "request_rate": 382.09, 2219 | "timestamp": "2020-12-27 23:12:1609110729", 2220 | "url": "/{c}/queries/{q}" 2221 | }, 2222 | { 2223 | "aiohttp": "3.7", 2224 | "concurrency": 256, 2225 | "db": "orm", 2226 | "errors": 0, 2227 | "latency": 1210.0, 2228 | "python": "3.9", 2229 | "queries": 10, 2230 | "request_rate": 192.9, 2231 | "timestamp": "2020-12-27 23:12:1609110741", 2232 | "url": "/{c}/queries/{q}" 2233 | }, 2234 | { 2235 | "aiohttp": "3.7", 2236 | "concurrency": 256, 2237 | "db": "orm", 2238 | "errors": 0, 2239 | "latency": 2260.0, 2240 | "python": "3.9", 2241 | "queries": 20, 2242 | "request_rate": 98.8, 2243 | "timestamp": "2020-12-27 23:12:1609110753", 2244 | "url": "/{c}/queries/{q}" 2245 | }, 2246 | { 2247 | "aiohttp": "3.7", 2248 | "concurrency": 32, 2249 | "db": "orm", 2250 | "errors": 0, 2251 | "latency": 31.48, 2252 | "python": "3.9", 2253 | "queries": "-", 2254 | "request_rate": 1014.1, 2255 | "timestamp": "2020-12-27 23:12:1609110764", 2256 | "url": "/{c}/fortunes" 2257 | }, 2258 | { 2259 | "aiohttp": "3.7", 2260 | "concurrency": 64, 2261 | "db": "orm", 2262 | "errors": 0, 2263 | "latency": 62.88, 2264 | "python": "3.9", 2265 | "queries": "-", 2266 | "request_rate": 1014.23, 2267 | "timestamp": "2020-12-27 23:12:1609110776", 2268 | "url": "/{c}/fortunes" 2269 | }, 2270 | { 2271 | "aiohttp": "3.7", 2272 | "concurrency": 128, 2273 | "db": "orm", 2274 | "errors": 0, 2275 | "latency": 122.89, 2276 | "python": "3.9", 2277 | "queries": "-", 2278 | "request_rate": 1032.16, 2279 | "timestamp": "2020-12-27 23:13:1609110787", 2280 | "url": "/{c}/fortunes" 2281 | }, 2282 | { 2283 | "aiohttp": "3.7", 2284 | "concurrency": 256, 2285 | "db": "orm", 2286 | "errors": 0, 2287 | "latency": 250.93, 2288 | "python": "3.9", 2289 | "queries": "-", 2290 | "request_rate": 995.15, 2291 | "timestamp": "2020-12-27 23:13:1609110799", 2292 | "url": "/{c}/fortunes" 2293 | }, 2294 | { 2295 | "aiohttp": "3.7", 2296 | "concurrency": 256, 2297 | "db": "orm", 2298 | "errors": 0, 2299 | "latency": 1200.0, 2300 | "python": "3.9", 2301 | "queries": 5, 2302 | "request_rate": 200.8, 2303 | "timestamp": "2020-12-27 23:13:1609110811", 2304 | "url": "/{c}/updates/{q}" 2305 | }, 2306 | { 2307 | "aiohttp": "3.7", 2308 | "concurrency": 256, 2309 | "db": "orm", 2310 | "errors": 1, 2311 | "latency": 2230.0, 2312 | "python": "3.9", 2313 | "queries": 10, 2314 | "request_rate": 101.5, 2315 | "timestamp": "2020-12-27 23:13:1609110823", 2316 | "url": "/{c}/updates/{q}" 2317 | }, 2318 | { 2319 | "aiohttp": "3.7", 2320 | "concurrency": 256, 2321 | "db": "orm", 2322 | "errors": 6, 2323 | "latency": 3060.0, 2324 | "python": "3.9", 2325 | "queries": 20, 2326 | "request_rate": 57.4, 2327 | "timestamp": "2020-12-27 23:13:1609110834", 2328 | "url": "/{c}/updates/{q}" 2329 | }, 2330 | { 2331 | "aiohttp": "3.7", 2332 | "concurrency": 32, 2333 | "db": "-", 2334 | "errors": 0, 2335 | "latency": 4.05, 2336 | "python": "3.9", 2337 | "queries": "-", 2338 | "request_rate": 7951.29, 2339 | "timestamp": "2020-12-27 23:14:1609110846", 2340 | "url": "/json" 2341 | }, 2342 | { 2343 | "aiohttp": "3.7", 2344 | "concurrency": 64, 2345 | "db": "-", 2346 | "errors": 0, 2347 | "latency": 6.83, 2348 | "python": "3.9", 2349 | "queries": "-", 2350 | "request_rate": 9366.43, 2351 | "timestamp": "2020-12-27 23:14:1609110858", 2352 | "url": "/json" 2353 | }, 2354 | { 2355 | "aiohttp": "3.7", 2356 | "concurrency": 128, 2357 | "db": "-", 2358 | "errors": 0, 2359 | "latency": 16.69, 2360 | "python": "3.9", 2361 | "queries": "-", 2362 | "request_rate": 7641.94, 2363 | "timestamp": "2020-12-27 23:14:1609110870", 2364 | "url": "/json" 2365 | }, 2366 | { 2367 | "aiohttp": "3.7", 2368 | "concurrency": 256, 2369 | "db": "-", 2370 | "errors": 0, 2371 | "latency": 31.56, 2372 | "python": "3.9", 2373 | "queries": "-", 2374 | "request_rate": 8054.84, 2375 | "timestamp": "2020-12-27 23:14:1609110882", 2376 | "url": "/json" 2377 | }, 2378 | { 2379 | "aiohttp": "3.7", 2380 | "concurrency": 32, 2381 | "db": "-", 2382 | "errors": 0, 2383 | "latency": 4.16, 2384 | "python": "3.9", 2385 | "queries": "-", 2386 | "request_rate": 7794.71, 2387 | "timestamp": "2020-12-27 23:14:1609110893", 2388 | "url": "/plaintext" 2389 | }, 2390 | { 2391 | "aiohttp": "3.7", 2392 | "concurrency": 64, 2393 | "db": "-", 2394 | "errors": 0, 2395 | "latency": 7.28, 2396 | "python": "3.9", 2397 | "queries": "-", 2398 | "request_rate": 8798.7, 2399 | "timestamp": "2020-12-27 23:15:1609110905", 2400 | "url": "/plaintext" 2401 | }, 2402 | { 2403 | "aiohttp": "3.7", 2404 | "concurrency": 128, 2405 | "db": "-", 2406 | "errors": 0, 2407 | "latency": 16.69, 2408 | "python": "3.9", 2409 | "queries": "-", 2410 | "request_rate": 7653.67, 2411 | "timestamp": "2020-12-27 23:15:1609110917", 2412 | "url": "/plaintext" 2413 | }, 2414 | { 2415 | "aiohttp": "3.7", 2416 | "concurrency": 256, 2417 | "db": "-", 2418 | "errors": 0, 2419 | "latency": 36.27, 2420 | "python": "3.9", 2421 | "queries": "-", 2422 | "request_rate": 7007.07, 2423 | "timestamp": "2020-12-27 23:15:1609110929", 2424 | "url": "/plaintext" 2425 | }, 2426 | { 2427 | "aiohttp": "3.7", 2428 | "concurrency": 32, 2429 | "db": "raw", 2430 | "errors": 0, 2431 | "latency": 12.07, 2432 | "python": "3.9", 2433 | "queries": "-", 2434 | "request_rate": 2667.37, 2435 | "timestamp": "2020-12-27 23:15:1609110941", 2436 | "url": "/{c}/db" 2437 | }, 2438 | { 2439 | "aiohttp": "3.7", 2440 | "concurrency": 64, 2441 | "db": "raw", 2442 | "errors": 0, 2443 | "latency": 28.51, 2444 | "python": "3.9", 2445 | "queries": "-", 2446 | "request_rate": 2593.92, 2447 | "timestamp": "2020-12-27 23:15:1609110952", 2448 | "url": "/{c}/db" 2449 | }, 2450 | { 2451 | "aiohttp": "3.7", 2452 | "concurrency": 128, 2453 | "db": "raw", 2454 | "errors": 0, 2455 | "latency": 69.53, 2456 | "python": "3.9", 2457 | "queries": "-", 2458 | "request_rate": 2490.52, 2459 | "timestamp": "2020-12-27 23:16:1609110964", 2460 | "url": "/{c}/db" 2461 | }, 2462 | { 2463 | "aiohttp": "3.7", 2464 | "concurrency": 256, 2465 | "db": "raw", 2466 | "errors": 0, 2467 | "latency": 136.81, 2468 | "python": "3.9", 2469 | "queries": "-", 2470 | "request_rate": 2505.06, 2471 | "timestamp": "2020-12-27 23:16:1609110976", 2472 | "url": "/{c}/db" 2473 | }, 2474 | { 2475 | "aiohttp": "3.7", 2476 | "concurrency": 256, 2477 | "db": "raw", 2478 | "errors": 0, 2479 | "latency": 295.67, 2480 | "python": "3.9", 2481 | "queries": 5, 2482 | "request_rate": 1098.39, 2483 | "timestamp": "2020-12-27 23:16:1609110988", 2484 | "url": "/{c}/queries/{q}" 2485 | }, 2486 | { 2487 | "aiohttp": "3.7", 2488 | "concurrency": 256, 2489 | "db": "raw", 2490 | "errors": 0, 2491 | "latency": 333.65, 2492 | "python": "3.9", 2493 | "queries": 10, 2494 | "request_rate": 872.23, 2495 | "timestamp": "2020-12-27 23:16:1609110999", 2496 | "url": "/{c}/queries/{q}" 2497 | }, 2498 | { 2499 | "aiohttp": "3.7", 2500 | "concurrency": 256, 2501 | "db": "raw", 2502 | "errors": 0, 2503 | "latency": 447.85, 2504 | "python": "3.9", 2505 | "queries": 20, 2506 | "request_rate": 593.25, 2507 | "timestamp": "2020-12-27 23:16:1609111010", 2508 | "url": "/{c}/queries/{q}" 2509 | }, 2510 | { 2511 | "aiohttp": "3.7", 2512 | "concurrency": 32, 2513 | "db": "raw", 2514 | "errors": 0, 2515 | "latency": 18.2, 2516 | "python": "3.9", 2517 | "queries": "-", 2518 | "request_rate": 1766.31, 2519 | "timestamp": "2020-12-27 23:17:1609111021", 2520 | "url": "/{c}/fortunes" 2521 | }, 2522 | { 2523 | "aiohttp": "3.7", 2524 | "concurrency": 64, 2525 | "db": "raw", 2526 | "errors": 0, 2527 | "latency": 40.77, 2528 | "python": "3.9", 2529 | "queries": "-", 2530 | "request_rate": 1669.28, 2531 | "timestamp": "2020-12-27 23:17:1609111033", 2532 | "url": "/{c}/fortunes" 2533 | }, 2534 | { 2535 | "aiohttp": "3.7", 2536 | "concurrency": 128, 2537 | "db": "raw", 2538 | "errors": 0, 2539 | "latency": 96.99, 2540 | "python": "3.9", 2541 | "queries": "-", 2542 | "request_rate": 1630.29, 2543 | "timestamp": "2020-12-27 23:17:1609111044", 2544 | "url": "/{c}/fortunes" 2545 | }, 2546 | { 2547 | "aiohttp": "3.7", 2548 | "concurrency": 256, 2549 | "db": "raw", 2550 | "errors": 0, 2551 | "latency": 210.18, 2552 | "python": "3.9", 2553 | "queries": "-", 2554 | "request_rate": 1675.5, 2555 | "timestamp": "2020-12-27 23:17:1609111055", 2556 | "url": "/{c}/fortunes" 2557 | }, 2558 | { 2559 | "aiohttp": "3.7", 2560 | "concurrency": 256, 2561 | "db": "raw", 2562 | "errors": 0, 2563 | "latency": 331.21, 2564 | "python": "3.9", 2565 | "queries": 5, 2566 | "request_rate": 788.67, 2567 | "timestamp": "2020-12-27 23:17:1609111067", 2568 | "url": "/{c}/updates/{q}" 2569 | }, 2570 | { 2571 | "aiohttp": "3.7", 2572 | "concurrency": 256, 2573 | "db": "raw", 2574 | "errors": 0, 2575 | "latency": 483.4, 2576 | "python": "3.9", 2577 | "queries": 10, 2578 | "request_rate": 518.57, 2579 | "timestamp": "2020-12-27 23:17:1609111078", 2580 | "url": "/{c}/updates/{q}" 2581 | }, 2582 | { 2583 | "aiohttp": "3.7", 2584 | "concurrency": 256, 2585 | "db": "raw", 2586 | "errors": 0, 2587 | "latency": 801.55, 2588 | "python": "3.9", 2589 | "queries": 20, 2590 | "request_rate": 305.16, 2591 | "timestamp": "2020-12-27 23:18:1609111089", 2592 | "url": "/{c}/updates/{q}" 2593 | } 2594 | ] -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import itertools 3 | import json 4 | import logging 5 | import os 6 | import re 7 | import shlex 8 | import subprocess 9 | import time 10 | from datetime import datetime 11 | from pathlib import Path 12 | 13 | import requests 14 | 15 | handler = logging.StreamHandler() 16 | handler.setLevel(logging.INFO) 17 | handler.setFormatter(logging.Formatter('%(asctime)s: %(message)s', datefmt='%H:%M:%S')) 18 | 19 | logger = logging.getLogger(__name__) 20 | logger.addHandler(handler) 21 | logger.setLevel(logging.INFO) 22 | 23 | REMOTE = os.getenv('REMOTE', 'FALSE').upper() in ('1', 'TRUE') 24 | if REMOTE: 25 | SSH_COMMAND = 'ssh', '-i', 'benchmarks.pem', os.environ['SSH_ADDRESS'] 26 | SERVER = os.environ['HTTP_ADDRESS'] 27 | print('Running on remote machine...') 28 | else: 29 | SSH_COMMAND = 'vagrant', 'ssh', '-c' 30 | SERVER = 'http://localhost:8080' 31 | print('Running on vagrant...') 32 | 33 | print(f'ssh command: {SSH_COMMAND}') 34 | print(f'server: {SERVER}') 35 | 36 | 37 | INSTALL_COMMAND = '~/env3{py_v}/bin/pip install "{package}"' 38 | RUN_COMMAND = 'sudo ~/env3{py_v}/bin/python serve.py' 39 | 40 | AIOH_VERSIONS = { 41 | '3.6': 'aiohttp>=3.6,<3.7', 42 | '3.7': 'aiohttp>=3.7,<3.8', 43 | } 44 | 45 | 46 | COMMAND_TEMPLATE = ( 47 | 'wrk -H "Host: localhost" -H "Connection: keep-alive" ' 48 | '-d {duration} -c {concurrency} --timeout 8 -t {threads} ' 49 | '"{server}{url}"' 50 | ) 51 | 52 | 53 | def run_remote(*commands, check=False): 54 | c = SSH_COMMAND + commands 55 | logger.info(f'running %s', c) 56 | subprocess.run(c, check=check) 57 | 58 | 59 | DURATION = 10 60 | results = [] 61 | 62 | raw_cases = itertools.product( 63 | (7, 8, 9), # python version 64 | tuple(AIOH_VERSIONS.keys()), # aiohttp version 65 | ('orm', 'raw'), # connection type 66 | ('/{c}/db', '/{c}/queries/{q}', '/{c}/fortunes', '/{c}/updates/{q}', '/json', '/plaintext'), # url 67 | (5, 10, 20), # queries 68 | (32, 64, 128, 256), # concurrency 69 | ) 70 | cases = [] 71 | for py_v, aiohttp_v, connection, url, queries, conc in raw_cases: 72 | 73 | if '{c}' not in url: 74 | if connection != 'orm': 75 | continue 76 | else: 77 | connection = '-' 78 | 79 | if '{q}' in url: 80 | if conc != 256: 81 | continue 82 | else: 83 | if queries != 20: 84 | continue 85 | else: 86 | queries = '-' 87 | 88 | cases.append((py_v, aiohttp_v, connection, url, queries, conc)) 89 | 90 | versions_previous = None 91 | case_count = len(cases) 92 | case_no = 0 93 | for py_v, aiohttp_v, connection, url, queries, conc in cases: 94 | start = time.time() 95 | case_no += 1 96 | url_ = url.format(q=queries, c=connection) 97 | logger.info('===============================================================================') 98 | logger.info(f' Python 3.{py_v}, aiohttp {aiohttp_v}, url {url_}, concurrency {conc}, case {case_no}/{case_count}') 99 | logger.info('===============================================================================') 100 | 101 | versions = py_v, aiohttp_v 102 | if versions != versions_previous: 103 | versions_previous = versions 104 | run_remote(INSTALL_COMMAND.format(py_v=py_v, package=AIOH_VERSIONS[aiohttp_v]), check=True) 105 | 106 | run_remote('sudo killall python') 107 | # run_remote('sudo service postgresql restart') 108 | # time.sleep(2) 109 | 110 | run = SSH_COMMAND + (RUN_COMMAND.format(py_v=py_v),) 111 | logger.info(f'starting %s', run) 112 | server = subprocess.Popen(run, env={'HOME': os.getenv('HOME'), 'PATH': os.getenv('PATH')}) 113 | 114 | try: 115 | logger.info('server started, waiting for it to be ready...') 116 | # prevent the vagrant/ssh messing up the tty 117 | subprocess.run(('stty', 'sane')) 118 | for i in range(40): 119 | time.sleep(0.1) 120 | try: 121 | r = requests.get(f'{SERVER}/plaintext', timeout=1) 122 | except Exception: 123 | continue 124 | if r.status_code == 200: 125 | subprocess.run(('stty', 'sane')) 126 | logger.info('server running after connection %d attempts', i) 127 | break 128 | 129 | r = requests.get(f'{SERVER}/plaintext') 130 | logger.info('plaintext response: "%s", status: %d, server: "%s"', r.text, r.status_code, r.headers['server']) 131 | assert r.status_code == 200 132 | server_python, server_aiohttp = re.search('Python/3\.(\d) *aiohttp/(\S{3})', r.headers['server']).groups() 133 | assert py_v == int(server_python) 134 | assert aiohttp_v[:3] == server_aiohttp 135 | 136 | logger.info('running wrk...') 137 | wrk_command = COMMAND_TEMPLATE.format(server=SERVER, concurrency=conc, duration=DURATION, threads=8, url=url_) 138 | p = subprocess.run(shlex.split(wrk_command), stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 139 | stdoe = p.stdout.decode() 140 | logger.info('wrk output: %s', stdoe.strip('\n ')) 141 | assert p.returncode == 0, f'bad exit code for wrk: {p.returncode}' 142 | finally: 143 | assert server.returncode is None, 'server command should still be running' 144 | server.terminate() 145 | 146 | request_rate = float(re.search('Requests/sec: *([\d.]+)', stdoe).groups()[0]) 147 | logger.info('request rate: %0.2f', request_rate) 148 | 149 | latency, s_ms = re.search(r'Latency *([\d.]+)(m?s)', stdoe).groups() 150 | latency = float(latency) 151 | if s_ms == 's': 152 | latency *= 1000 153 | logger.info('latency: %0.2f', latency) 154 | 155 | m = re.search('Non-2xx or 3xx responses: *(\d+)', stdoe) 156 | errors = int(m.groups()[0]) if m else 0 157 | m = re.search('Socket errors: *connect (\d+), read (\d+), write (\d+), timeout (\d+)', stdoe) 158 | if m: 159 | errors += sum(map(int, m.groups())) 160 | logger.info('errors: %d', errors) 161 | logger.info('time taken: %0.2fs', time.time() - start) 162 | 163 | results.append({ 164 | 'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%s'), 165 | 'python': f'3.{py_v}', 166 | 'aiohttp': aiohttp_v, 167 | 'concurrency': conc, 168 | 'queries': queries, 169 | 'url': url, 170 | 'db': connection, 171 | 'errors': errors, 172 | 'request_rate': request_rate, 173 | 'latency': latency, 174 | }) 175 | 176 | p = Path(__file__).parent.joinpath('results.json') 177 | with p.open('w') as f: 178 | json.dump(results, f, indent=2, sort_keys=True) 179 | --------------------------------------------------------------------------------