Thursday, August 10, 2017

Gevent + Requests Performance With verify=True/False

If you use gevent with requests.get on a HTTPS URL with the default verify=True enabled, you'll see almost 2x longer execution times than with verify=False.

Here are the results:
verify=True took: 40.3454630375 secs
verify=False took: 39.3803040981 secs
gevent verify=True took: 2.23735189438 secs
gevent verify=False took: 1.58263015747 secs
I suspect that gevent is having trouble using pyopenssl concurrently because it's a C library.

Tuesday, June 27, 2017

Backing up or dumping a memcached server

I was needing to move from an old cache server to a larger one, but I wanted to do it without flushing cache.

The first thing I came across was this "memcached-tool" which has a dump command:

There's another article that mentions using memdump and memcat:

Unfortunately, those methods only dumped a few mb of data. This post explains why:

You can only dump one page per slab class (1MB of data)
So, I ended up writing a script that loops through the expected cache keys, gets the data in cache, then sets the data in the new cache server.

Monday, June 12, 2017

Gunicorn - "Resource temporarily unavailable"

Are you seeing this error in your logs while your server is under high load?:
[error] 10#0: *14843 connect() to unix:/tmp/gunicorn.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client:, server: , request: "GET / HTTP/1.0", upstream: "http://unix:/tmp/gunicorn.sock:/", host: ""
I ended up making an example dockerfile with nginx + gunicorn + flask to reproduce this problem:

Bumping the "net.core.somaxconn" setting ended up fixing it.

Friday, March 17, 2017

SQLAlchemy - empty lists + in_() causing crazy queries (before 1.2.0)

Before SQLAlchemy 1.2.0, if you use an empty list with in_(), it will emit some crazy SQL that will query your entire table. The best solution is probably to upgrade to SQLAlchemy 1.2.0.

Monday, March 13, 2017

The Robustness Principle

I learned about this at a talk called "Implementing Evolvable APIs" at SXSW:

For example, making an API that throws errors when an unexpected parameter is provided is a bad idea. What if you need to make changes to the client to add the new parameter? You will need to make sure you deploy the code on the server side first, otherwise it will cause errors.

Tuesday, February 14, 2017

SQLAlchemy - DISTINCT, LIMIT, or OFFSET Causing Subqueries

This section at the bottom of The Zen of Eager loading is really important:
When using joined eager loading, if the query contains a modifier that impacts the rows returned externally to the joins, such as when using DISTINCT, LIMIT, OFFSET or equivalent, the completed statement is first wrapped inside a subquery, and the joins used specifically for joined eager loading are applied to the subquery. SQLAlchemy’s joined eager loading goes the extra mile, and then ten miles further, to absolutely ensure that it does not affect the end result of the query, only the way collections and related objects are loaded, no matter what the format of the query is.
I made an example to illustrate this here:

On MySQL this can be responsible for some really poor query performance, because it can cause it to use temporary tables and filesort.

The best way I've found to prevent the subqueries is by first querying for the ids only, then running another query that includes all relations. For example:
ids = session.query(