UnoPim is an open-source product information management (PIM) system built on Laravel. It helps businesses manage and organize product data efficiently. In this post, we show that UnoPim supports 10 million products out of the box — with measurements to prove it.

Most PIM platforms describe scale with adjectives. We prefer measurements. Therefore, we built a live catalog of 10,001,236 products — 5 locales, 3 channels, 50 attribute families, and 50,000 categories. Then we measured how UnoPim behaves on it.
The short version: you do not need to re-architect or tune your way to this scale. There are no forks and no custom storage layer. Instead, the standard product model, Elasticsearch integration, and queue pipeline carry the load. In other words, this is not a guide on how to get there — it is proof that you are already there.
Every figure below comes from the live 10M catalog. Moreover, we ran everything on a single 32-core / 128 GB NVMe host with MySQL 8, Elasticsearch 8.19, and PHP 8.4. All services were co-located. As a result, a clustered deployment only improves on these numbers.
| Metric @ 10M products | Result (p95) |
|---|---|
| Product grid: load / filter / sort / paginate — single editor | 104 ms |
| Product grid under 50 concurrent editors | 233 ms |
| Catalog search (Elasticsearch), full stack | 130 ms · 48–443 ms by term |
| REST API single-product read | 59.8 ms |
| Full Elasticsearch reindex, 10M documents | 30.2 min at 5,526 docs/sec, online |
| Concurrent editor sessions sustained | 50 sessions at 227–267 req/sec, zero errors |
Every interactive read stays well inside the 500 ms editor-productivity target. Here is the dashboard of the instance under test. You can also explore a live UnoPim yourself on the official demo:

UnoPim rejects the classic EAV value-table design. Instead, a product’s entire attribute payload — every locale and every channel — lives in one JSON column on the product row itself. Consequently, reading a product is a single indexed fetch, not a 40-way join across value tables with billions of rows.
That is why the product grid loads in 104 ms and an API read finishes in under 60 ms. Ten million products means ten million rows. Furthermore, the read cost never grows with attribute count.

Grids, filters, and search run against an Elasticsearch index sized for the catalog. Meanwhile, the relational database remains the source of truth. Below, a search for “wireless earbuds” finds 98,350 matches out of 10 million products in interactive time:

The index is derived data. Rebuilding all 10 million documents from the database takes 30.2 minutes — online, with no downtime window. Elasticsearch also stays optional: small catalogs run the pure-database search path with zero extra infrastructure. To enable it, follow the configuration guide.
Imports, exports, and reindexing run as queue jobs that process fixed-size batches. Nothing catalog-sized ever runs inside a web request. Throughput scales by adding queue workers. In addition, long-running jobs survive worker restarts and resume where they left off.
Catalog size does not leak into screens that skip the product table. We measured every non-product admin grid against the same 10M catalog. Each one answers in under 52 ms: attributes in 34.2 ms, and the job tracker in 51.4 ms. Above all, the 50,000-node category tree renders in 47.5 ms, because nested-set storage turns the whole tree into a single range scan.

Opening a product for editing tells the same story. The full localized, channel-scoped payload, the completeness score, and the associations all resolve from that single product row:

Our measurements ran on one host. Even so, UnoPim carried 10 million products without a dedicated tier per service. For production, use the reference shapes below. The app tier is stateless; therefore, editor traffic and import throughput grow independently:
| Catalog | App | Database | Elasticsearch | Workers |
|---|---|---|---|---|
| ≤100k | single server, 16 GB total; Elasticsearch optional below ~250k | 2 | ||
| 1M | 8 vCPU / 16 GB | 8 vCPU / 32 GB | 8 GB heap | 4 |
| 5M | 2× 8 vCPU | 16 vCPU / 64 GB | 16 GB heap | 8 |
| 10M | 2–4× 8 vCPU | 32 vCPU / 128 GB + replica | 3 × 16 GB heap | 8–16 |
A few practical notes. Queue-worker count is the import-throughput dial. Elasticsearch heap of roughly index size ÷ 4 is a workable start. Audit history grows fastest under active enrichment, so set a retention policy at install time. Full setup steps live in the UnoPim documentation.
Ten million products is not a hosting tier. Rather, it is the result of design decisions: one row per product, search delegated to Elasticsearch, and every unbounded operation queued and chunked. All of these decisions are visible in the open-source codebase. The measurements above show what they deliver.
In short, UnoPim supports 10 million products today. Your catalog can grow from a hundred products to ten million on the same platform — without re-platforming.
We hope you found these measurements useful. If you have questions about running UnoPim at scale, leave a comment below — we’re happy to help.
Need help with a large catalog? Contact our team
Error: Contact form not found.
If you have more details or questions, you can reply to the received confirmation email.
Back to Home
Be the first to comment.