Benchmark Results: Frappe vs. Django Login Performance under Concurrent Load

Hi everyone,

I recently set up a load-testing environment using Apache JMeter to benchmark the login endpoint performance of Frappe. While Frappe’s baseline performance is fantastic (vastly outperforming my baseline Django tests), I am looking for community advice on how we can tune the framework to eliminate bottlenecks and achieve a 100% success rate—while keeping response times low—even under brutal concurrency spikes.

System & Environment Specs

All tests were run locally (native execution, no virtualization):

  • Hardware: Apple Macbook Air M2 (8 CPU cores), 16 GB LPDDR5 RAM
  • OS: macOS Sequoia 15.7.7
  • Python: 3.14.4 (Homebrew build)
  • WSGI: Gunicorn (4 workers, sync class, --preload enabled).
  • Databases: MariaDB for Frappe (with Redis cache/sessions).
  • Frappe Version: 17.0.0-dev (Production Mode)

The Bottleneck: Extreme Concurrency & Response Times

Under high load with a gradual ramp-up (e.g., 2,000 to 4,000 threads spread over 30–50 seconds), Frappe easily maintains a 100% success rate with average latencies well under 50ms.

However, when testing aggressive traffic spikes (a short 10-second ramp-up), not only does the success rate drop significantly, but response times become a major concern. Given that all tests were run locally—meaning zero external network latency—the spike to ~4000ms average response time at 4K threads indicates a severe internal bottleneck.

Threads Ramp-up Success Rate Avg Latency 95th Percentile Throughput
500 10s 100.00% ~26 ms ~69 ms ~100/s
1000 10s ~99.9% ~780 ms ~1224 ms ~166/s
2000 10s ~80.0% ~2764 ms ~7774 ms ~251/s
4000 10s ~59.1% ~4016 ms ~7776 ms ~404/s

(Test Config: GET to /login –> POST to /api/method/login submitting credentials)

The Goal: Reaching Maximum Efficiency

I want to figure out how to push those 2K and 4K (10s ramp-up) numbers to a 100% success rate and bring the response times back down to acceptable levels.

  1. Gunicorn Tweaks: Should I move away from the default sync workers to gthread or gevent workers for Frappe to handle concurrent connections better?
  2. Database Pooling: Are there specific MariaDB connection limits or timeout configurations that usually cause these dropped requests and delayed response times during a spike?
  3. OS/Environment Limits: Given this is running locally, could this primarily be macOS socket/file descriptor limits (ulimit) bottlenecking the test, rather than the framework itself?

For those who want to dig deeper into the exact JMeter HTML reports, test plans, and the Django comparison data, you can find my full repository here:
Frappe_and_Django_Framework_LoadTests

I’d love to collaborate on finding the optimal configuration to squeeze every bit of performance out of Frappe under heavy load!

1 Like

Hi. I think you mistyped your Frappe version

Hi @satys and welcome to the community

Its really great what you are doing in trying to improve the performance of the Frappe Framework. (very) Slowly I believe the community contributions towards Frappe ecosystem is increasing. According to one estimate its 20% versus Frappe Technologies Pvt. Ltd’s 80%. I hope one day it can reach the 51% threshold.
I wonder if there is also a Database expert who can analyze the MariaDB against known standard benchmarks

Best of luck and let us know how it goes