Skip to content
Notifications
Clear all

Using Metabase in production for 50 dashboards - what broke

1 Posts
1 Users
0 Reactions
2 Views
(@devops_grandad)
Estimable Member
Joined: 2 months ago
Posts: 100
Topic starter   [#20163]

Alright, let's cut through the marketing fluff. We rolled out Metabase in production about 18 months ago, aiming to give various teams self-serve analytics. We hit about 50 active, "important" dashboards used by department heads. It wasn't a huge deployment, but it was business-critical. And then, predictably, things started to creak and then break. Not in a dramatic, fiery crash, but in the death-by-a-thousand-papercuts way that grinds productivity to a halt.

Here's what actually broke or became a massive pain point, specifically at that scale:

**Performance & Database Load**
* **Ad-hoc queries killing the warehouse:** The promise of "self-serve" is also its curse. A well-meaning user would build a question with five massive table joins, no filters on date ranges, and set it to auto-refresh every 10 minutes on a dashboard. We'd find these not through Metabase but by spotting the runaway queries in our PostgreSQL warehouse. Metabase's query explanations are basic; real performance profiling requires external tools.
* **Dashboard load times:** A dashboard with 10-12 cards, even simple ones, could take 8-12 seconds to load. The main culprit was sequential query execution. Metabase would fire the queries one after another, rather than in parallel, so latency stacked up. We had to get clever with caching, which is its own can of worms.

**Caching: A Band-Aid, Not a Cure**
We leaned heavily on database-level materialized views and Metabase's cache. The cache configuration is fiddly, and invalidation logic can be opaque. You end up with stale data, or you set durations so short the cache is useless. Here's a snippet of the kind of config we had to tweam endlessly:

```yaml
# metabase.yml snippet - trying to manage the bleed
cache-config:
# Default cache TTL in minutes
max-ttl: 120
# Multi-tenant setups get weird with cache isolation
cache-namespace: "metabase_tenant_1"
# Often had to restart after cache config changes
```

**Administration Overhead**
* **The "Wild West" of Definitions:** With 50 dashboards, you get 50 definitions of what "Monthly Revenue" means. Metabase has "official" metrics and models now, but adoption is manual. We spent more time auditing and fixing queries than we'd like.
* **Version Control & Governance is Bolted-On:** Dashboards and questions are stored in the application database. Tracking changes, doing peer reviews, or rolling back a broken card is a manual, error-prone process. There are third-party tools and some API scripts, but it's not like having your infra as code.
* **Alerting Scale:** Setting up 20-30 performance alerts on dashboards (e.g., "if sales drop below threshold") becomes a management nightmare. Each is a separate entity, and there's no templating or bulk operations.

**The Scaling Limit**
The real breaking point wasn't the number of dashboards, but the number of *concurrent users* hitting them. Once we had about 15-20 people actively building or viewing complex dashboards at the same time, the Metabase app server (we ran the open-source version on a decent VM) would become sluggish. Thread pools would exhaust, and the UI would just hang. We looked at the Enterprise edition for better performance controls, but the jump was significant.

In the end, Metabase is fantastic for getting started and for small-team agility. But at the 50-dashboard mark, where it transitions from a useful tool to a core piece of reporting infrastructure, you hit the wall. You're no longer a Metabase user; you're a Metabase *administrator*, and the tooling for that role isn't its strength. We've since moved to a more layered approach: Metabase for lightweight, team-specific stuff, and a different, more governed platform for the core company metrics.



   
Quote