You're noticing timeouts on queries running on your PostgreSQL database? Or just slower response to queries? And when you look at RDS monitoring the cpu and memory look like the machine is doing nothing?
There are two main causes I've found for this: lock contention and IOPS limits. Today I'm talking about the most likely of them: lock contention.
So, first things first, how to identify if you have lock contention? There are two queries that will help you identify what's going on:
SELECT COUNT(*) FROM pg_locks
This will show you how many locks are in your system at a point in time. If the database is not being used, the number should be zero. If it's being used, I'd expect the locks to go up and sometimes fall down to zero (we're talking about low load scenarios). If that doesn't happen (or rarely happens) you might have slow transactions helding locks for a long time and making everything else wait for them.
You can confirm if that's the case with this query:
SELECT * FROM pg_stat_activity WHERE state <> 'idle'
You'll be looking at some states of
idle in transaction and/or with wait_type
If you see these signs, there are 2 strategies you can use to speed things up:
- Optimise the queries that are causing the locks. The quickest return will probably come up from adding some indexes, I'd recommend taking a look at PostgresSQL's wiki index usage query for where you'll get the biggest return.
- Reduce locks in your application (usually be eliminating queries). Remember those less than clear queries you were thinking of cleaning up another day? It might be the right time.
And that's how you can make your app faster.