Readyset Adds New Query Capabilities With the Bucket Function
5 min read
•
15 days ago

Readyset is a cache layer that sits between the application and the database, acting as a cache for supported queries and proxying unsupported queries upstream. This means that any query Readyset supports is theoretically supported by the upstream database, but not necessarily the other way around.
What if that is no longer the case? What if Readyset can support queries that the upstream database can’t? What if you could keep your relational database and add extra functionality without any plugins or extensions?
Readyset’s streaming Dataflow engine works well for systems that periodically poll for results or require quick updates, such as monitoring and near-real-time time-series workloads. While these queries can technically be served by upstream relational databases, their execution time is often too long to be practical.
A New Query Pattern Enabled by Readyset’s Bucket Function
This month, we introduced a Readyset-specific built-in function, which doesn’t exist in upstream databases, called Bucket.
The Bucket function helps you group time based data into regular intervals, for example by hour, day, or month, so you can easily see trends over time such as daily sales totals or hourly user activity.
It takes two arguments: the first is a timestamp or datetime column, and the second is an interval. The interval is a string that follows the format <positive integer> <unit>[s], where the unit can be year, month, day, hour, minute, or second. You can then use the result in a GROUP BY clause with an aggregate function to summarize your data, similar to how you might analyze events in a time-series database.
You can also take it a step further and take advantage of Readyset’s parameterization, like so:
then query by binding literals to the placeholders/parameters:
Examples and Considerations:
Let’s take a look at the NYC Yellow Taxi Trips dataset for the 4 years from 2020 to 2023, this is roughly 134 million records after some cleaning (like removing any rows after the date 31 Dec 2023). We will only import a few selected columns into a postgresql-15 database table.
While we will only use two of these columns, we still want the rows to be reasonably sized for the purpose of this demo. We run this demo on a local machine with 55 free GBs of memory.
Keep in mind that Bucket is not supported in PostgreSQL, so we will try to simulate it using PostgreSQL built-in functions:
Giving us the output:
This takes 20.46 seconds to execute on average.
Now, let’s create a cache in Readyset with the new Bucket function and query it:
Giving us the exact output:
The cache takes only a few minutes to build. Querying it returns results in 5.6 milliseconds, with the cache read itself taking just 0.396 milliseconds! That’s almost 365× faster, with no additional expression nesting.
Let’s also insert twenty thousand rows into the top two buckets and see how fast Readyset can keep the cache updated. We’ll use a simple script to generate data, making sure the generated fare_amount exceeds the previous maximum. After doing this, we see that Readyset replicates the changes almost instantly and still produces results in a familiar 5.6 milliseconds, with the cache read taking 0.468 milliseconds.
When working with this query pattern, keep in mind that it will be fully materialized, meaning all rows are stored in memory. Depending on the size of your dataset and the predicates used, this can increase memory usage during cache creation.
To optimize memory, you can create a filtered view that includes only the most relevant time period or subset of data. Using this view as the input to the cache helps Readyset focus on active data, reducing memory requirements and improving efficiency.
Readyset’s Approach to Time-Series–Like Workloads
We’re not building a full-fledged time-series database, and that’s by design. While this pattern might look familiar if you’ve worked with time-series systems, we’re not aiming to compete with purpose-built solutions that handle both storage and execution.
Instead, our goal with this new pattern is to give you a practical alternative for handling time-series–like workloads without needing to introduce a new database into your infrastructure. If you’ve ever avoided building certain features because they seemed too complex or required a specialized database, Readyset can now help you unlock that functionality using your existing relational database.
You manage the storage. We’ll take care of making the queries fast. Let us know what other time-series functionality you’d like to see in Readyset.
Conclusion
With features like Bucket, Readyset isn’t just speeding up your existing queries—it’s enabling new ones your database can’t easily handle. It’s more than a cache layer; it’s a tool that extends your application’s capabilities. More power, better performance, zero database changes—just plug it in and go.
Authors