8. How to Choose a High-Performance CMS? AnQiCMS's Technology Behind Supporting 5 Million PV Websites
Tag: High-performance CMS, AnQiCMS, Architecture, Caching
category_id: 35

A website with 5 million daily PVs, what configuration is needed?
This issue has come up in several corporate projects. To conclude: even with an 8-core 16G server using WordPress, it might not be enough, and you also need load balancing and Redis clusters.In terms of AnQiCMS, a single node with 4 cores and 8G can handle it.
Where is the gap? Architecture design and execution efficiency.
What does 5 million PV mean?

Daily PV 5 million, convert it:
- About 3,500 page requests per minute
- Peak of about 100-200 concurrent requests per second (considering uneven traffic distribution)
- If the website has a large amount of content, the database pressure is also great
This level is a large site for personal blogs, but a small and medium-sized scale for corporate websites. However, for corporate websites, this concurrency level has already made it difficult for PHP-based CMSs.
The architecture of AnQiCMS

The architecture of AnQiCMS is relatively simple, without too many bells and whistles:
Nginx → AnQiCMS (Go+Iris) → MySQL
This is three layers. Nginx acts as a reverse proxy and static resource service, AnQiCMS handles business logic, and MySQL is used for data persistence.
No Redis, no Kafka, no message queue. This architecture is sufficient for an enterprise website.
Database design

Table structure
The article table, category table, tag table, comment table, the structure is not complex. Main fields:
- Article table: id, title, content, category_id, create_time, update_time
- Category table: id, name, parent_id, sort
- Tag table: id, name
- Article tag relationship table: article_id, tag_id
No redundant design, fewer fields, high query efficiency.
Index
Query list page by index, avoid full table scan:
- The article table: a composite index of category_id, status, and create_time
- The category table: an index of parent_id and sort
- The tag table: an index of name
For a website with 5 million PV, a reasonable index design is more effective than any black technology.
Caching strategy

page cache
AnQiCMS supports page caching, used in templatescacheTag control:
{% cache 3600 %}
这个模块缓存1小时
{% endcache %}
The granularity of the home page cache can be larger, such as caching for 2 hours. The cache time of the category list page can be shorter, such as 30 minutes. The detail page is generally not cached because the content is frequently updated.
Fragment cache
Page-level cache is sometimes not fine enough. For example, the navigation bar on the homepage does not need to be refreshed every time, but the content list does. Fragment caching can break the page into pieces and control the cache time separately.
Data caching
Configuration information, site information, and other almost unchanged data are stored directly in memory and do not need to be checked in the database every time.
Concurrency Handling

Goroutine
Each HTTP request is processed by a goroutine. If there are 200 concurrent requests, there are 200 goroutines. These goroutines share an operating system thread pool, with low switching overhead.
Connection pool
Database connections use a connection pool, reusing established connections, and do not need to be created each time. The size of the connection pool is adjusted according to the server configuration, with a default of 20.
Asynchronous logging
Log writing is asynchronous and does not affect request processing. The log level can be set, generally set to warn or higher in production environments to reduce disk I/O.
Actual data

I ran a set of tests to see the performance of AnQiCMS under different concurrency.
| Concurrency count | Average Response Time | QPS | Memory usage |
|---|---|---|---|
| 10 | 25ms | 400 | 45MB |
| 50 | 35ms | 1400 | 55MB |
| 100 | 45ms | 2200 | 70MB |
| 200 | 80ms | 2500 | 80 MB |
| 500 | 150ms | 3300 | 95MB |
| 1000 | 300ms | 3300 | 110MB |
Note, this is the result on a 2-core 4G server. QPS reached a bottleneck at 1000 concurrents (3300), not because the performance has reached its limit, but because the 2-core 4G CPU could not keep up.
Changed to a 4-core 8G server, QPS can reach about 5000 at 1000 concurrents, with memory usage of 120MB.
Server configuration recommendation

Small and medium-sized enterprise station (daily PV below 10,000)
2 cores 4GB, sufficient. AnQiCMS runs smoothly on this machine.
Medium-sized enterprise site (daily PV 1-100,000)
4 cores 8GB, sufficient. There will be no problem during peak concurrency.
Large enterprise site (daily PV 10-500,000)
8 cores 16GB, it is recommended to add Redis cache. The database can be on a separate machine.
Large website (daily PV over 500,000)
Multi-node deployment. AnQiCMS supports multi-node and can be load balanced. The database uses MySQL master-slave, read-write separation.
Performance optimization

Nginx optimization
Enable Gzip compression, disable access logs (or only record error level), set static file cache time.
gzip on;
gzip_types text/css application/javascript;
access_log off;
MySQL optimization
Adjust innodb_buffer_pool_size to 50%-70% of physical memory, adjust query_cache_size, set appropriate connection numbers.
Content distribution
Place static resources such as images on CDN to reduce server pressure. AnQiCMS image upload supports direct upload to OSS or S3, and CDN acceleration takes effect immediately.
Summary

The solution for a website with 5 million PV is:
4-core 8GB server + MySQL + Nginx reverse proxy, a single node can handle it.
If using WordPress, the same traffic may require starting at 8-core 16GB, plus Redis and load balancing, the complexity of the architecture will increase by two levels.
The savings are not just the server cost, but also the operation and maintenance effort. For enterprise IT teams, the simpler the architecture, the lower the maintenance cost.
