MongoDB Developer Centerchevron-right
Developer Topicschevron-right

Serverless Instances Billing 101: How to Optimize Your Bill with Indexing

Vishal DhimanPublished Jul 29, 2022 • Updated Jul 29, 2022
Copy Link
facebook icontwitter iconlinkedin icon
random alt
Rate this article
Serverless solutions are quickly gaining traction among developers and organizations alike as a means to move fast, minimize overhead, and optimize costs. But shifting from a traditional pre-provisioned and predictable monthly bill to a consumption or usage-based model can sometimes result in confusion around how that bill is generated. In this article, we’ll take you through the basics of our serverless billing model and give you tips on how to best optimize your serverless database for cost efficiency.

What are serverless instances?

MongoDB Atlas serverless instances, recently announced as generally available, provide an on-demand serverless endpoint for your application with no sizing required. You simply choose a cloud provider and region to get started, and as your app grows, your serverless database will seamlessly scale based on demand and only charge for the resources you use.
Unlike our traditional clusters, serverless instances offer a fundamentally different pricing model that is primarily metered on reads, writes, and storage with automatic tiered discounts on reads as your usage scales. So, you can start small without any upfront commitments and never worry about paying for unused resources if your workload is idle.
Serverless Database Pricing
Pay only for the operations you run.
Read Processing Unit (RPU)Number of read operations* to the database

*Sum of documents read divided by 4KB and index bytes read divided by 256 bytes
$0.10/million for the first 50 million per day*

*Daily RPU tiers: Next 500 million: $0.05/million Reads thereafter: $0.01/million
Write Processing Unit (WPU)Number of write operations* to the database

*Sum of documents and index bytes written, divided by 1KB
StorageData and indexes stored on the database$0.25/GB-month
Standard BackupDownload and restore of backup snapshots*

*2 free daily snapshots included per serverless instance

*To download or restore the data
Serverless Continuous Backup35-day backup retention for daily snapshots$0.20/GB-month
Data TransferInbound/outbound data to/from the database$0.015 - $0.10/GB*

*Depending on traffic source and destination
At first glance, read processing units (RPU) and write processing units (WPU) might be new units to you, so let’s quickly dig into what they mean. We use RPUs and WPUs to quantify the amount of work the database has to do to service a query, or to perform a write. To put it simply, a read processing unit (RPU) refers to the read operations to the database and one RPU is typically equivalent to either one document or one index entry scanned. Similarly, write processing units (WPUs) are write operations to the database, with one WPU typically being equivalent to each document or index entry written. For further explanation of cost units, please refer to our documentation.
Now that you have a basic understanding of the pricing model, let’s go through an example to provide more context and tips on how to ensure your operations are best optimized to minimize costs.
For this example, we’ll be using the sample dataset in Atlas. To use sample data, simply go to your serverless instance deployment and select “Load Sample Dataset” from the dropdown as seen below.
Load sample dataset This will load a few collections, such as weather data and Airbnb listing data. Note that loading the sample dataset will consume approximately one million WPUs (less than $1 in most supported regions), and you will be billed accordingly
Now, let’s take a look at what happens when we interact with our data and do some search queries.

Scenario 1: Query on unindexed fields

For this exercise, I chose the sample_weatherdata collection. While looking at the data in the Atlas Collections view, it’s clear that the weather data collection has information from various places and that most locations have a call letter code as a convenient way to identify where this weather reading data was taken.
For this example, let’s simulate what would happen if a user comes to your weather app and does a lookup by a geographic location. In this weather data collection, geographic locations can be identified by callLetters, which are specific codes for various weather stations across the world. I arbitrarily picked station code “ESVJ,” which is a weather buoy in the Atlantic Ocean. 
Here is what we see when we run this query in Atlas Data Explorer: 
Document returned in collection
We can see this query returns three records. Now, let’s take a look at how many RPUs this query would cost me. Roughly, we should remember that:
RPU ≅ number of documents scanned. (In reality, if documents are larger than 4KB, then you might be charged more than 1 RPU per document.)
To execute the previous query, a full collection scan is required. Therefore, to run the query, all 10,000 documents in the collection are scanned, resulting in 10,000 RPUs (since each document is less than 4KB in length).
I took this query and ran this nearly 3,000 times through a shell script. This will simulate around 3,000 users coming to an app to check the weather in a day. Here is the code behind the script:
As expected, 3,000 iterations will be 10,000 * 3,000 = 30,000,000 RPUs = 30MM RPU = $3.00. 
You can see the invoice below:
Atlas serverless invoice
Based on this, the cost per user for this application would be $0.10 per user (calculated as: 30,000,000 / 3000 = 10,000 RPUs = $0.10). 
The cost of $0.10 per user seems to be very high for a database lookup, because if this weather app were to scale to reach a similar level of activity to Accuweather, who sees about 9.5B weather requests in a day, you’d be paying close to around $1 billion in database costs. By leaving your query this way, it’s likely that you’d be faced with an unexpectedly high bill as your usage scales—falling into a common trap that many new serverless users face. 
To avoid this problem, we recommend that you follow MongoDB best practices and index your data to optimize your queries for both performance and cost. Indexes are special data structures that store a small portion of the collection's data set in an easy-to-traverse form.
Without indexes, MongoDB must perform a collection scan—i.e., scan every document in a collection—to select those documents that match the query statement (something you just saw in the example above). By adding an index to appropriate queries, you can limit the number of documents it must inspect, significantly reducing the operations you are charged for.
Let’s look at how indexing can help you reduce your RPUs significantly.

Scenario two: Querying with indexed fields

First, let’s create a simple index on the field ‘callLetters’:
Create index on collection
This operation will typically finish within 2-3 seconds. For reference, we can see the size of the index created on the index tab:
Index size of callLetters_1 index
Due to the data structure of the index, the exact number of index reads are hard to compute. However, we can run the same script again for 3,000 iterations and again look at the invoice to compare.
Atlas serverless invoice
As seen on the invoice above, 3,000 queries on the indexed field did not change my bill at all, but you can see a slight increase in the RPUs (highlighted in blue). This is because the cost of running this operation was less than $0.01. Comparing the number of RPUs from the previous screenshot, we can see that they increased by 0.035M, which is around 35,000 RPUs, in contrast to the 30 million RPUs from the un-indexed query:
(30,000,000 - 35,000)/30,000,000 * 100 = 99.88% reduction
We can see that by simply adding the above index, we were able to reduce the cost per user to roughly $0.0001167 (calculated as: 35,000 / 3000 = 11.67 RPUs = $0.0001167), which is a huge cost savings compared to the previous cost of $0.10/user.
Therefore, indexing not only helps with improving the performance and scale of your queries, but it can also reduce your consumed RPUs significantly, which reduces your costs. Note that there can be rare scenarios where this is not true (where the size of the index is much larger than the number of documents). However, in most cases, you should see a significant reduction in cost and an improvement in performance.

Take action to optimize your costs today

As you can see, adopting a usage-based pricing model can sometimes require you to be extra diligent in ensuring your data structure and queries are optimized. But when done correctly, the time spent to do those optimizations often pays off in more ways than one. 
If you’re unsure of where to start, we have built-in monitoring tools available in the Atlas UI that can help you. The performance advisor automatically monitors your database for slow-running queries and will suggest new indexes to help improve query performance. Or, if you’re looking to investigate slow-running queries further, you can use query profiler to view a breakdown of all slow-running queries that occurred in the last 24 hours. If you prefer a terminal experience, you can also analyze your query performance in the MongoDB Shell or in MongoDB Compass. 
If you need further assistance, you can always contact our support team via chat or the MongoDB support portal

Copy Link
facebook icontwitter iconlinkedin icon
Rate this article
Improve Your App's Search Results with Auto-Tuning

Sep 07, 2022
Build Your Own Function Retry Mechanism with Realm

Jul 19, 2022
Bringing your data to your Wrist with the MongoDB Atlas Data API and Fitbit

Sep 02, 2022
Build a Cocktail API with Beanie and MongoDB

Sep 23, 2022
Table of Contents