Calendar² and The Events Calendar on 10,000 events, measured.
In our test with 10,000 events, Calendar² served the busiest month in 90 ms and The Events Calendar 6.18.1 in 197 ms, and the month page was 22 KB gzipped against 553 KB. This page sets out how we measured it, every figure we got, the pages where we were slower, and how to run the same test yourself.
- busiest month in Calendar², against 197 ms
- 90 ms
- that month page gzipped, against 553 KB
- 22 KB
- to migrate 1,000 events
- 26 s
- On every calendar page we could compare like for like, Calendar² answered faster and ran fewer database queries. The gap was widest on the busiest day: 57 ms against 1,251 ms.
- Calendar²’s month pages were a tenth of the size or less, which matters on a phone.
- Calendar² was worse in two places: its iCal feed is bigger, and with 1,000 repeating series added, its busiest month slowed to about half a second. Both are below.
- This is our own test, on one machine, of a build from the day before 1.0.0. Views haven’t been re-measured on 1.0.0 or 1.1.0 yet. Treat it as what we measured, not a guarantee for your site.
Both sites held the same 10,000 events. Each figure is the median of 20 requests, with the two sites’ requests taken in turn so that anything else the machine was doing affected both. Times are to the first byte of the response, measured on the machine itself, so there’s no network in them.
| Page | TEC ms | Calendar² ms | TEC queries | Calendar² queries | TEC page | Calendar² page |
|---|---|---|---|---|---|---|
| Month view, this month/events/month/ | 122 | 56 | 44 | 25 | 224 KB | 21 KB |
| Month view, busiest monthabout 15% of all events | 197 | 90 | 44 | 25 | 553 KB | 22 KB |
| List viewfirst page | 135 | 40 | 68 | 25 | 24 KB | 18 KB |
| Day view, busiest dayabout 240 events on one Saturday | 1,251 | 57 | 74 | 27 | 111 KB | 21 KB |
| Single eventone event page | 107 | 29 | 60 | 30 | 15 KB | 14 KB |
| Categorythe most-used category | 92 | 31 | 76 | 28 | 26 KB | 19 KB |
| Keyword searcha word in about 1% of titles | 191 | 46 | 72 | 25 | 25 KB | 19 KB |
| iCal feedsubscribe link | 52 | 8 | 186 | 12 | 12 KB | 52 KB |
| Admin events listlogged in, page 1 | 266 | 57 | 109 | 48 | – | – |
| Edit an eventlogged in | 486 | 69 | 103 | 59 | – | – |
Page size is the HTML alone, gzipped. With stylesheets and scripts added, the busiest month page came to about 672 KB on The Events Calendar and 33 KB on Calendar². Peak memory per request, from the same day’s query-logging runs: the list 22 to 32 MB on The Events Calendar against 12 MB, a single event 16 to 56 MB against 10 MB, and this month’s view 31 MB against 12 MB. The Events Calendar’s memory varied between runs, so it’s shown as a range.
We ran the same pages again with PHP limited to 128 MB. Neither plugin ran out of memory, but the machine was busy during that run, so we don’t quote its times.
When you save an event, Calendar² works out the dates it falls on, once, and writes each date as a row in a small table of its own, indexed by start and end time. Repeating events are written up to 24 months ahead by default, and a background job keeps extending that as time passes. So a weekly event becomes a row per week when it’s saved, not a calculation on every page view.
A calendar page then asks that table for the dates in its window. The month view reads that month’s rows through the index and loads full event details only for the events the grid has room to show. The list shows 20 events a page and the day view 40, so a busy day is split into pages rather than drawn all at once.
The Events Calendar’s own performance guide, updated 21 October 2026, suggests turning on its Month View cache, showing fewer events per day in month view, and cutting how far ahead repeating events are created, which it says is 60 months by default. It also says that caching alone may not be enough and you may need more server resources. We ran it on its default settings.
For more on how repeats work in Calendar², see repeating events.
- The iCal feed. Calendar²’s was faster but bigger: 52 KB gzipped against 12 KB. Calendar²’s feed carries up to 500 upcoming events; we didn’t check how many The Events Calendar’s carries by default.
- Repeating events. The Events Calendar’s free plugin has no repeating events, so the comparison above uses one-off events only. On Calendar² alone we added 1,000 two-year series (500 daily, 500 weekly), which took the table to 420,255 dates. The busiest month then took about 500 ms and 62 MB, because the month view reads every date in the month. That run was on a busier machine (load average about 4), and it’s the page we most want to make faster.
- Venue and organiser pages. Calendar²’s took 53 to 55 ms. The Events Calendar’s free plugin answered the same addresses with a page the size of the home page, so we haven’t put the two side by side.
- Caching. Neither site had a page cache or a persistent object cache, which is the worst case for both. With full-page caching, most visitors would see neither plugin’s PHP time.
We also timed Calendar²’s switch, version 1.0.0, on the same data on 20 October 2026, after a request on Reddit for memory and query counts as well as time. Every PHP process the step started was measured. Times are wall clock, including start-up; the 10,000-event range covers two runs.
| Step | 1,000: time | Peak MB | Queries | 10,000: time | Peak MB | Queries |
|---|---|---|---|---|---|---|
| Dry run | 3.0 s | 84 | 190 | 5.6–7.6 s | 102 | 442 |
| Prepare (in the background) | 16.9 s | 108 | 165,819 | 251–490 s | 340 | 1,638,625 |
| Switch | 6.3 s | 90 | 3,532 | 13.1–13.4 s | 134 | 31,562 |
| Roll back | 3.1 s | 84 | 1,824 | 6.6–7.1 s | 122 | 16,560 |
It took 26 s to migrate 1,000 events, end to end: dry run, prepare and switch. Prepare runs in the background while the site stays on The Events Calendar, which is why 4 to 8 minutes at 10,000 events doesn’t mean downtime.
Fixed in 1.1.0
The benchmark showed prepare writing far more than it needed to, and its memory growing with the size of the calendar. Version 1.1.0 writes in batches and frees memory between them. On the same data, prepare’s queries fell from 165,819 to 43,638 at 1,000 events and from 1,638,625 to 413,657 at 10,000, and peak memory at 10,000 from 340 MB to 96 MB. We don’t quote new times for it: the machine was too busy that afternoon for a fair comparison.
The steps themselves are in the switching guide.
- Machine: a MacBook running other work at the same time, with Docker. Each WordPress and each database container was limited to 2 CPUs and 768 MB of memory.
- Software: the WordPress image for PHP 8.3 with Apache, a fixed pool of 10 PHP workers on each site, MariaDB 11, the Twenty Twenty-Five theme, pretty permalinks and the New York timezone. WP-Cron was off during the timed runs. No page cache and no persistent object cache.
- Plugins: The Events Calendar 6.18.1, the free plugin, on its default settings. Calendar² at build c6e96cd from 17 October 2026, the day before 1.0.0, for the page timings, and 1.0.0 for the switch. The current version of The Events Calendar on 25 October 2026 is 6.18.2.
- Data: 10,000 one-off events with 180 categories, 3,334 venues and 2,000 organisers, generated by a script with a fixed seed and modelled on a real local-news events calendar. Events are spread over the 12 months either side of 17 October 2026, with about 15% in November 2026 and about 240 on Saturday 14 November. 5% are all-day and 5% run over several days.
- Loading: events were created through The Events Calendar’s public PHP functions, then counted through its REST API and its own tables before the database was saved. Calendar²’s site is the same database, moved across with Calendar²’s own switch.
- PHP memory limit: 256 MB for the page timings.
Our scripts are in a private repository, so here’s the method. Anyone with Docker can repeat it.
- Set up two identical WordPress sites, each with its own database, with the same limits on CPU and memory. Install The Events Calendar on both.
- On the first, create your events through The Events Calendar, then copy that database to the second site and switch it to Calendar² (Calendar² → Migrate). Both sites now hold the same events.
- Add a small must-use plugin to both that reports, in response headers, PHP time, peak memory (
memory_get_peak_usage(true)) and the query count ($wpdb->num_queries). - Pick matching pages on each: month, busiest month, list, busiest day, a single event, a category, a search, the iCal feed, and the admin list and edit screens.
- Request each page once to warm up, then 20 times, alternating between the two sites, with a fresh connection each time. Record the median time to first byte, the headers and the gzipped size of the HTML.
- Turn off WP-Cron while you measure, and note the machine’s load average with each run. Throw away runs taken while the machine was busy.
For the switch, run each step with WP-CLI (wp calendar2 migrate dry-run, then prepare, switch and rollback), and measure every PHP process each step starts, not just the first one.
- Page timings, queries and sizes: our run of 17 October 2026 at 10,000 events with a 256 MB PHP limit (host load average under 2). Memory: the same day’s query-logging runs.
- Repeating series on Calendar²: our run of 17 October 2026, 1,000 series added to the 10,000 events (420,255 dates), host load average about 4.
- The switch: our benchmark of version 1.0.0, 20 October 2026, on the same data. The 1.1.0 prepare counts: the same data and stack, later that day.
- The Events Calendar’s performance advice: its calendar performance guide, updated 21 October 2026, checked 25 October 2026.
- The Events Calendar’s current version (6.18.2): WordPress.org, checked 25 October 2026.
- Spotted a mistake, or got different numbers on your own machine? Email brandon@bsquared.software and we’ll look into it and correct this page.
Got a big calendar?
Tell us how many events you have and how your site is hosted, and a person replies, usually within two UK working days, with what we’d expect.