Dripshop Infrastructure Case Study

90% Cost Reduction

How Dripshop Migrated from GCP Kubernetes to Dedicated Servers

$20K Before (GKE) → $2K After (Dedicated)

🎯 The Result

52,000 TPS at the database layer. 10,000+ concurrent users. 90% cost reduction.

This is the story of how we did it—and why managed infrastructure isn't always the answer.

The Problem: GKE at Scale Gets Expensive

Dripshop started on Google Kubernetes Engine—the standard choice for modern containerized applications. But as traffic grew, so did the bill.

💸 $20,000/month

Monthly GKE infrastructure spend including compute, managed databases, and egress costs for global users.

📦 20 Instances at Peak

During NFT drops, we scaled to 20 instances (16 vCPU, 32GB RAM each). Total: 320 vCPUs, 640GB RAM.

⏱️ 75ms Latency

PgBouncer connection pooling became a bottleneck, adding significant latency to database operations.

📈 Overprovisioning

Node pools required overprovisioning to handle traffic spikes, meaning we paid for resources we rarely used.

🐘 AlloyDB: "Managed" But Not Really

GCP's AlloyDB promised a fully managed PostgreSQL experience, but reality was different. We still had to manually tune work_mem, shared_buffers, and other parameters. It only supported PgBouncer for connection pooling—no Odyssey option. Managed in name, DIY in practice.

The Real Problem: We were paying premium prices for "managed" services while still doing the optimization work ourselves—and hitting the limits of single-threaded tools.

🤔 The Decision: Going Against the Grain

The cloud-native playbook says use managed Kubernetes.

It's "easier to operate." It "scales automatically." It's "the modern way." But we asked ourselves: what are we actually paying for?

Auto-scaling → We could handle this ourselves with PM2 cluster mode

Managed control planes → We didn't need them for a stable workload

Premium pricing → We were paying cloud tax on commodity compute

The New Infrastructure

Three dedicated servers from ServerBasket—bare metal machines with serious specifications:

GCP Kubernetes $20K → Dedicated Servers $2K

🏗️ The Architecture: Three Servers, Zero Compromise

We split responsibilities cleanly across three dedicated servers, each with 256 cores and 768GB RAM.

1

Server 1: Backend

256 cores • 768GB RAM

  • 🔄 PM2 Cluster Mode
  • 200 Node.js Workers
  • 🌐 API + Business Logic
  • 📊 Load Balancing
2

Server 2: Cache + Search

256 cores • 768GB RAM

  • 🐉 DragonflyDB (Redis)
  • 🔍 OpenSearch
  • 🔐 Session Store
  • 📦 Queue Management
3

Server 3: Database

256 cores • 768GB RAM

  • 🐘 PostgreSQL 18
  • 🌊 Odyssey Pooler
  • 📍 PostGIS Extension
  • 🧩 19 Extensions

🔗 Why This Separation Works

Backend: Pure compute—no contention with I/O services. Cache: Memory-bound DragonflyDB + heavier OpenSearch queries isolated. Database: Full resources for PostgreSQL with massive shared_buffers allocation.

🧩 PostgreSQL Extensions: Supercharging the Database

We leverage 19 PostgreSQL extensions to optimize performance, enable advanced queries, and add specialized functionality.

🚀 Performance Extensions

  • pg_stat_statements for query analysis
  • pg_buffercache for buffer inspection
  • pg_prewarm for cache warming
  • pg_visibility for visibility maps

🔍 Search & Indexing

  • pg_trgm for fuzzy text search
  • fuzzystrmatch for string matching
  • bloom for bloom filter indexes
  • btree_gin / btree_gist for composite indexes

🌍 Geospatial (PostGIS)

  • postgis for spatial data
  • postgis_raster for raster data
  • postgis_topology for topological models
  • postgis_tiger_geocoder for US geocoding

🛠️ Data Types & Utilities

  • uuid-ossp for UUID generation
  • pgcrypto for encryption
  • hstore for key-value storage
  • citext / intarray / tablefunc

💡 Why Extensions Matter

These extensions let us handle fuzzy search, geospatial queries, advanced indexing, and performance monitoring inside PostgreSQL—eliminating the need for external services and reducing network round-trips.

🧪 The Experimental Stack

Instead of just migrating our existing stack, we re-evaluated every component with modern multi-core hardware in mind.

Connection Pooling: Odyssey

PgBouncer is single-threaded—on a 256-core machine, that's a bottleneck. Odyssey from Yandex is multi-threaded, using 64 worker threads to handle connections.

20x Faster

vs PgBouncer (2,650 → 51,807 TPS)

In-Memory Cache: DragonflyDB

Redis is single-threaded by design. DragonflyDB is a drop-in replacement that's multi-threaded from the ground up. Same API, dramatically better throughput on multi-core machines.

25x Faster

vs Redis on 256-core machine

Zero Code Changes Required: We exported Redis data as an RDB file and imported it directly into DragonflyDB. All existing Redis clients work without any modification—true drop-in replacement.

📊 Benchmark Results: Odyssey vs PgBouncer

We ran comprehensive benchmarks with 200 clients and 100 threads over 60 seconds. The results speak for themselves.

💡 Key Insight

Odyssey with 64 worker threads nearly matches direct PostgreSQL performance while still providing connection pooling, transaction management, and 10,000+ client connection support.

🐉 DragonflyDB vs Redis

🏆 The Results: Numbers Don't Lie

After completing the migration from GKE + AlloyDB to dedicated servers, here's where we landed:

52K

TPS

Database transactions per second—impossible to achieve with AlloyDB + PgBouncer limitations.

10K+

Users/sec

Concurrent users handled comfortably with room to spare.

45ms

P95

API response time at the 95th percentile—down from 150ms.

90%

Savings

Monthly infrastructure cost reduced from $20,000 to $2,000.

Resource Utilization

15-25%

CPU Average

30-35%

Memory Usage

3-4x

Growth Headroom

💡 The Irony

With dedicated servers, we have full control over PostgreSQL tuning—work_mem, shared_buffers, connection pooling—and achieved 52K TPS. The "managed" AlloyDB couldn't come close, yet cost 10x more.

Made with