{"id":5150,"date":"2025-06-17T08:00:06","date_gmt":"2025-06-17T15:00:06","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sql\/?p=5150"},"modified":"2025-06-16T12:12:23","modified_gmt":"2025-06-16T19:12:23","slug":"auto-scaling-hyperscale-elastic-pools","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sql\/auto-scaling-hyperscale-elastic-pools\/","title":{"rendered":"An open-source AutoScaler for Azure SQL Hyperscale Elastic Pools"},"content":{"rendered":"<p><div class=\"alert alert-info\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Guest Post<\/strong><\/p><em>Larry Silverman is the Chief Technology Officer at TrackAbout, Inc. (a Datacor company) and a long-time user of Azure SQL Database and SQL Server. In this blog post Larry shares a novel open-source solution which addresses a core need for their business. Thanks, Larry! <\/div><\/em><\/p>\n<p><a href=\"https:\/\/corp.trackabout.com\/\"><span data-contrast=\"none\">TrackAbout<\/span><\/a> is a worldwide provider of <span data-contrast=\"auto\">SaaS applications for tracking reusable, durable, physical assets like chemical containers and gas cylinders. With over 22 million physical assets tracked across 350 customers, each with their own Azure SQL database, optimizing our infrastructure for both cost and performance is a critical, ongoing mission.<\/span><\/p>\n<p><span data-contrast=\"auto\">Our journey with Microsoft technologies goes back to our founding in 2002. We started by racking our own servers, moved to managed hosting, and finally migrated to Azure in 2016 to gain more control and scalability. A core part of our architecture today is Azure SQL Database <\/span><span data-contrast=\"auto\">elastic pools<\/span><span data-contrast=\"auto\">.<\/span><\/p>\n<p><span data-contrast=\"auto\">When <\/span><a href=\"https:\/\/aka.ms\/HSEP\"><span data-contrast=\"none\">Azure SQL Hyperscale elastic pools<\/span><\/a><span data-contrast=\"auto\"> was <\/span><a href=\"https:\/\/aka.ms\/HSEP-GA\"><span data-contrast=\"none\">announced<\/span><\/a><span data-contrast=\"auto\">, we were intrigued. The promise of scaling up and down in just a few minutes<\/span><span data-contrast=\"auto\"> seemed ideal for our largest, most demanding customers. It offered potential improvements in both performance and cost. However, we discovered a key limitation: <strong>Microsoft didn\u2019t provide built-in autoscaling for Hyperscale elastic pools.<\/strong><\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">That limitation led us to create <\/span><a href=\"https:\/\/github.com\/trackabout\/azure-sql-hyperscale-elasticpool-autoscaler\"><b><span data-contrast=\"none\">AutoScaler<\/span><\/b><\/a><span data-contrast=\"auto\">, the open-source solution we\u2019re sharing with you today. This post will walk you through our approach for auto-scaling Hyperscale elastic pools and show how you can use it to optimize your own Azure SQL Hyperscale deployments.<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">The Solution: The AutoScaler Azure Function<\/span><\/h2>\n<p><span data-contrast=\"auto\">The AutoScaler is a timer-triggered Azure function written in C#. It&#8217;s designed to be lightweight and efficient. A single instance can manage multiple elastic pools on the same Azure SQL Server, or you can run multiple instances of the function for different servers. You can find the code in <\/span><a href=\"https:\/\/github.com\/trackabout\/azure-sql-hyperscale-elasticpool-autoscaler\"><span data-contrast=\"none\">our GitHub repo<\/span><\/a><span data-contrast=\"auto\">.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Key Features at a Glance<\/span><\/h2>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">Multi-Pool Management: A single instance of the AutoScaler can manage multiple elastic pools on a single Azure SQL Server.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">Configurable Scaling Logic: Tailor the scaling behavior to your specific workload patterns.<\/span><span data-ccp-props=\"{}\"> You can skip steps to scale up faster if desired.<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">Hysteresis-based Scaling: Avoids erratic scaling with a smart, two-window approach.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">Comprehensive Logging: Detailed logging provides a clear view of the AutoScaler\u2019s actions. Optional logging to a SQL table is also available.<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">Managed Identity Support: Securely connect to your Azure SQL resources using Azure Managed Identities.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<\/ul>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">How It Works: Metrics and Logic<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;335559738&quot;:360,&quot;335559739&quot;:80}\">\u00a0<\/span><\/h2>\n<h3 aria-level=\"2\"><span data-contrast=\"none\">Metrics Monitored<\/span><\/h3>\n<p><span data-contrast=\"auto\">Instead of requiring a separate database to store metrics, the AutoScaler makes decisions using the historical data found in the <\/span><a href=\"https:\/\/learn.microsoft.com\/sql\/relational-databases\/system-dynamic-management-views\/sys-dm-elastic-pool-resource-stats-azure-sql-database?view=azuresqldb-current\"><span data-contrast=\"none\">sys.dm_elastic_pool_resource_stats<\/span><\/a><span data-contrast=\"auto\"> view. This view provides about <\/span><span data-contrast=\"auto\">40<\/span><span data-contrast=\"auto\"> minutes of historical readings, which is plenty of data to make informed scaling decisions. Scaling commands are automatically recorded in <\/span><span data-contrast=\"auto\">the Azure SQL server\u2019s <\/span><a href=\"https:\/\/learn.microsoft.com\/sql\/relational-databases\/system-dynamic-management-views\/sys-dm-operation-status-azure-sql-database?view=azuresqldb-current\"><span data-contrast=\"none\">sys.dm_operation_status<\/span><\/a><span data-contrast=\"auto\"> view, and also in the<\/span><span data-contrast=\"auto\"> Azure Activity Log. We also provide an option to log scaling decisions and the data used to make those decisions to a SQL table for long-term analysis.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Based on our nine years of experience running elastic pools, we chose to monitor these four key metrics for our workload:<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">Average CPU Percentage<\/span><\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"2\" data-aria-level=\"1\"><span data-contrast=\"auto\">SQL Instance CPU Percentage<\/span><\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"3\" data-aria-level=\"1\"><span data-contrast=\"auto\">Worker Percentage<\/span><\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"4\" data-aria-level=\"1\"><span data-contrast=\"auto\">Data IO Percentage<\/span><\/li>\n<\/ul>\n<p><span data-contrast=\"auto\">Your workload might be different than ours. The function is extensible, so you could, for example, add monitoring for <\/span><span data-contrast=\"auto\">Log IO Percentage<\/span><span data-contrast=\"auto\"> if that&#8217;s a bottleneck for your application.<\/span><\/p>\n<h3 aria-level=\"2\"><span data-contrast=\"none\">Hysteresis-Based Scaling Logic<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;335559738&quot;:160,&quot;335559739&quot;:80}\">\u00a0<\/span><\/h3>\n<p><span data-contrast=\"auto\">The core of the AutoScaler is its <a href=\"https:\/\/en.wikipedia.org\/wiki\/Hysteresis\">hysteresis<\/a>-based scaling logic, which prevents &#8220;thrashing&#8221; (rapidly scaling up and down). We delay scaling decisions until metrics have remained above or below a threshold for a sustained period.<\/span><\/p>\n<p><span data-contrast=\"auto\">To do this, we measure averages over two sliding windows:<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"4\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">A <\/span><b><span data-contrast=\"auto\">short window<\/span><\/b><span data-contrast=\"auto\"> (e.g., 5 minutes) to detect sudden spikes.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"4\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"2\" data-aria-level=\"1\"><span data-contrast=\"auto\">A <\/span><b><span data-contrast=\"auto\">long window<\/span><\/b><span data-contrast=\"auto\"> (e.g., 15\u201330 minutes) to confirm a sustained change in load.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<\/ul>\n<p><span data-contrast=\"auto\">When deciding whether to scale <\/span><b><span data-contrast=\"auto\">up<\/span><\/b><span data-contrast=\"auto\">, we check if a metric has breached its high threshold in the short window. But we don&#8217;t act immediately. We wait to see if the long-window average <\/span><i><span data-contrast=\"auto\">also<\/span><\/i><span data-contrast=\"auto\"> exceeds the threshold. If only the short window is high, the scaler waits, as it might be a temporary burst.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">When deciding whether to scale <\/span><b><span data-contrast=\"auto\">down<\/span><\/b><span data-contrast=\"auto\">, we require that <\/span><i><span data-contrast=\"auto\">all<\/span><\/i><span data-contrast=\"auto\"> four metrics remain below their &#8220;low&#8221; thresholds across both the short and long windows before we reduce capacity.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">This logic can be summarized as follows:<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"6\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><b><span data-contrast=\"auto\">Scale Up <\/span><\/b><span data-contrast=\"auto\">if <\/span><b><span data-contrast=\"auto\">any one <\/span><\/b><span data-contrast=\"auto\">of the four metric averages for <\/span><b><span data-contrast=\"auto\">both<\/span><\/b><span data-contrast=\"auto\"> the long and short windows are at or above their high threshold.<\/span><\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"6\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"2\" data-aria-level=\"1\"><b><span data-contrast=\"auto\">Scale Down <\/span><\/b><span data-contrast=\"auto\">if <\/span><b><span data-contrast=\"auto\">all four<\/span><\/b><span data-contrast=\"auto\"> of the metric averages for <\/span><b><span data-contrast=\"auto\">both<\/span><\/b><span data-contrast=\"auto\"> the long and short windows are at or below their low threshold.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<\/ul>\n<p><span data-contrast=\"auto\">You can configure much of this, including the high\/low thresholds for each metric, the lookback windows, and the floor\/ceiling vCore levels to ensure you stay within your budget.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Getting Started<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;335559738&quot;:360,&quot;335559739&quot;:80}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">We&#8217;ve tried to make it as easy as possible to get up and running. The project&#8217;s GitHub repository has all the details, but here&#8217;s the gist:<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<ol>\n<li data-leveltext=\"%1.\" data-font=\"\" data-listid=\"8\" data-list-defn-props=\"{&quot;335552541&quot;:0,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769242&quot;:[65533,0],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;%1.&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><b><span data-contrast=\"auto\">Deploy the Azure Function:<\/span><\/b><span data-contrast=\"auto\"> The core of the AutoScaler.<\/span><span data-ccp-props=\"{&quot;134233117&quot;:true,&quot;134233118&quot;:true,&quot;201341983&quot;:0,&quot;335559740&quot;:240}\"> There&#8217;s a GitHub Actions workflow in the repo which demonstrates how to deploy.<\/span><\/li>\n<\/ol>\n<ol>\n<li data-leveltext=\"%1.\" data-font=\"\" data-listid=\"8\" data-list-defn-props=\"{&quot;335552541&quot;:0,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769242&quot;:[65533,0],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;%1.&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"2\" data-aria-level=\"1\"><b><span data-contrast=\"auto\">Configure Your Settings:<\/span><\/b><span data-contrast=\"auto\"> Set up your connection strings, thresholds, and other parameters in the Function&#8217;s application settings.<\/span><span data-ccp-props=\"{&quot;134233117&quot;:true,&quot;134233118&quot;:true,&quot;201341983&quot;:0,&quot;335559740&quot;:240}\">\u00a0<\/span><\/li>\n<\/ol>\n<ol>\n<li data-leveltext=\"%1.\" data-font=\"\" data-listid=\"8\" data-list-defn-props=\"{&quot;335552541&quot;:0,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769242&quot;:[65533,0],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;%1.&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"3\" data-aria-level=\"1\"><b><span data-contrast=\"auto\">Set Permissions:<\/span><\/b><span data-contrast=\"auto\"> Ensure the Function&#8217;s managed identity has the necessary permissions to monitor and scale your elastic pools.<\/span><span data-ccp-props=\"{&quot;134233117&quot;:true,&quot;134233118&quot;:true,&quot;201341983&quot;:0,&quot;335559740&quot;:240}\">\u00a0<\/span><\/li>\n<\/ol>\n<p><span data-contrast=\"auto\">We strongly encourage you to explore the docs, code and unit tests, and run your own load test to get comfortable with how the AutoScaler behaves in your environment.<\/span><span data-ccp-props=\"{}\"> There are load testing instructions in the repo.<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Logic Flowchart<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;335559738&quot;:360,&quot;335559739&quot;:80}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">The following flow chart illustrates the logic of the autoscaler (click to enlarge) each time the timer trigger fires.<\/span><\/p>\n<p><span data-ccp-props=\"{}\">\u00a0<a href=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2025\/06\/flowchart.png\"><img decoding=\"async\" class=\"aligncenter wp-image-5152 size-large\" src=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2025\/06\/flowchart-580x1024.png\" alt=\"flowchart image\" width=\"580\" height=\"1024\" srcset=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2025\/06\/flowchart-580x1024.png 580w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2025\/06\/flowchart-170x300.png 170w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2025\/06\/flowchart-768x1357.png 768w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2025\/06\/flowchart-869x1536.png 869w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2025\/06\/flowchart-1159x2048.png 1159w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2025\/06\/flowchart.png 1415w\" sizes=\"(max-width: 580px) 100vw, 580px\" \/><\/a><\/span><\/p>\n<h2 aria-level=\"1\">Warning<\/h2>\n<p aria-level=\"1\"><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;335559738&quot;:360,&quot;335559739&quot;:80}\">AutoScaler works by invoking the standard Azure SQL elastic pool scaling APIs. When the pool scales, <strong>client connections are dropped<\/strong>. Your client code must be built for resiliency to handle this disconnect and retry interrupted transactions. Refer to the <a href=\"https:\/\/learn.microsoft.com\/azure\/azure-sql\/database\/elastic-pool-scale\">documentation<\/a> for guidance on how to do this correctly. There are libraries that can help.<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Disclaimer<\/span><\/h2>\n<p><span data-contrast=\"auto\">As with any cloud resource,<\/span><span data-contrast=\"auto\"> Azure SQL <\/span><span data-contrast=\"auto\">elastic pools<\/span><span data-contrast=\"auto\"> can incur <\/span><b><span data-contrast=\"auto\">very high costs <\/span><\/b><b><span data-contrast=\"auto\">if not used appropriately<\/span><\/b><span data-contrast=\"auto\">. You are solely responsible for any costs you incur by using this code. We strongly recommend that you study the project, review the unit tests, and run your own load tests to ensure the AutoScaler behaves in a manner you are comfortable with before deploying to production.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Join the Community<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;335559738&quot;:360,&quot;335559739&quot;:80}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">This project was inspired by Microsoft&#8217;s own <\/span><a href=\"https:\/\/techcommunity.microsoft.com\/blog\/azuresqlblog\/autoscaling-azure-sql-hyperscale\/1149025\"><span data-contrast=\"none\">past work<\/span><\/a><span data-contrast=\"auto\"> on autoscaling, and we&#8217;re thrilled to contribute back to the community. We welcome your feedback, suggestions, and contributions. Check out <\/span><a href=\"https:\/\/github.com\/trackabout\/azure-sql-hyperscale-elasticpool-autoscaler\"><span data-contrast=\"none\">the project on GitHub<\/span><\/a><span data-contrast=\"auto\">, and let&#8217;s work together to make it even better.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Happy Scaling,<\/span><\/p>\n<p><span data-contrast=\"auto\">Larry Silverman<\/span>\n<span data-contrast=\"auto\">Chief Technology Officer<\/span>\n<span data-contrast=\"auto\">TrackAbout, Inc.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>TrackAbout is a worldwide provider of SaaS applications for tracking reusable, durable, physical assets like chemical containers and gas cylinders. With over 22 million physical assets tracked across 350 customers, each with their own Azure SQL database, optimizing our infrastructure for both cost and performance is a critical, ongoing mission. Our journey with Microsoft technologies [&hellip;]<\/p>\n","protected":false},"author":184097,"featured_media":81,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,594],"tags":[],"class_list":["post-5150","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sql","category-hyperscale"],"acf":[],"blog_post_summary":"<p>TrackAbout is a worldwide provider of SaaS applications for tracking reusable, durable, physical assets like chemical containers and gas cylinders. With over 22 million physical assets tracked across 350 customers, each with their own Azure SQL database, optimizing our infrastructure for both cost and performance is a critical, ongoing mission. Our journey with Microsoft technologies [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/5150","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/users\/184097"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/comments?post=5150"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/5150\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media\/81"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media?parent=5150"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/categories?post=5150"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/tags?post=5150"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}