<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Multi-AZ | John Nessime</title>
	<atom:link href="https://john-nessime.com/blog/tag/multi-az/feed/" rel="self" type="application/rss+xml" />
	<link>https://john-nessime.com/blog/tag/multi-az/</link>
	<description>Cloud, DevOps, Data &#38; AI — Built, Tested, Explained</description>
	<lastBuildDate>Mon, 12 Oct 2026 06:08:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.4</generator>

<image>
	<url>https://john-nessime.com/blog/wp-content/uploads/2026/07/cropped-jn-32x32.png</url>
	<title>Multi-AZ | John Nessime</title>
	<link>https://john-nessime.com/blog/tag/multi-az/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Oracle on EC2 vs RDS: Why the License Math Doesn&#8217;t Save You</title>
		<link>https://john-nessime.com/blog/technical-guides/oracle-on-ec2-vs-rds/</link>
		
		<dc:creator><![CDATA[John Nessime]]></dc:creator>
		<pubDate>Mon, 12 Oct 2026 06:08:11 +0000</pubDate>
				<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Technical Guides]]></category>
		<category><![CDATA[Amazon EC2]]></category>
		<category><![CDATA[Amazon RDS]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[BYOL]]></category>
		<category><![CDATA[Cost Optimization]]></category>
		<category><![CDATA[Data Guard]]></category>
		<category><![CDATA[Database Migration]]></category>
		<category><![CDATA[FinOps]]></category>
		<category><![CDATA[Multi-AZ]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle Licensing]]></category>
		<category><![CDATA[RDS Custom]]></category>
		<category><![CDATA[Vendor Lock-In]]></category>
		<guid isPermaLink="false">https://john-nessime.com/blog/?p=386</guid>

					<description><![CDATA[<p>Oracle counts a vCPU the same way on EC2 and on RDS, so the platform choice never saves you licensing money. What it does change is sysdba access, block size and file limits, who owns backups and failover, and the Multi-AZ setting that quietly doubles your BYOL count.</p>
<p>The post <a href="https://john-nessime.com/blog/technical-guides/oracle-on-ec2-vs-rds/">Oracle on EC2 vs RDS: Why the License Math Doesn&#8217;t Save You</a> appeared first on <a href="https://john-nessime.com/blog">John Nessime</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">The finance lead asks a fair question in the migration kickoff: &#8220;If we move Oracle to RDS instead of EC2, how much do we save on licensing?&#8221;</p>



<p class="wp-block-paragraph">Nothing. Not a cent. Oracle counts a vCPU on Amazon RDS exactly the way it counts a vCPU on Amazon EC2, and it says so in the same paragraph of the same policy document. The managed service does not buy you a discount on the software.</p>



<p class="wp-block-paragraph">That single fact reshapes the whole argument. Once the license line is identical on both sides of the page, Oracle on EC2 vs RDS stops being a cost comparison and becomes a much more interesting question: which set of constraints can your application actually live inside? This post walks through the real differences, the places each option quietly hurts, the middle option that is being retired, and a decision procedure you can run before anyone opens a pricing calculator.</p>



<h2 class="wp-block-heading">Start with the thing that is not a difference</h2>



<p class="wp-block-paragraph">Oracle publishes a policy called &#8220;Licensing Oracle Software in the Cloud Computing Environment.&#8221; It names a short list of Authorized Cloud Environments, and both Amazon EC2 and Amazon RDS are on it, alongside Microsoft Azure and Google Cloud Platform. Inside an Authorized Cloud Environment the counting rules are these:</p>



<ul class="wp-block-list">
<li>Two vCPUs count as one Oracle Processor license when multi-threading of processor cores is enabled.</li>



<li>One vCPU counts as one Processor license when multi-threading is not enabled.</li>



<li>The Oracle Processor Core Factor Table does not apply. The 0.5 multiplier you rely on for x86 hardware in your own data center is simply gone.</li>



<li>For Standard Edition products, instances with four or fewer vCPUs count as one socket. Above four, every four vCPUs rounded up to the nearest multiple of four equals one socket.</li>



<li>Standard Edition 2 may only be licensed on instances up to eight AWS vCPUs. That is a hard ceiling, and it is the single most common reason an SE2 estate has to become an Enterprise Edition estate on migration.</li>
</ul>



<p class="wp-block-paragraph">None of those rules distinguish EC2 from RDS. The policy treats them as the same environment for counting purposes.</p>



<p class="wp-block-paragraph">There is one genuine licensing difference, and it is narrow. RDS offers a License Included model where AWS holds the Oracle license and bundles it into the instance-hour rate. That model covers Standard Edition 2 only. Enterprise Edition on RDS is bring-your-own-license, full stop. On EC2 there is no License Included option at all, so every Oracle database you run there is BYOL by definition.</p>



<p class="wp-block-paragraph">Worth reading the footer of that Oracle policy document, too. It states that the document is for educational purposes and may not be incorporated into any contract. Your Oracle Master Agreement and ordering documents are what actually bind you. The cloud policy is how Oracle says it will behave, not what it promised in writing, and it can change without notice. Pin a copy of the version in force when you deploy and file it with your architecture decision record.</p>



<h3 class="wp-block-heading">Find out what you are actually using first</h3>



<p class="wp-block-paragraph">Before you compare anything, find out which licensable options and management packs your current database is touching. Oracle tracks this itself. The feature usage view records every separately licensed feature the database has detected in use, which is exactly what an auditor looks at.</p>



<pre class="wp-block-code"><code>-- Which separately licensed features has this database touched?
SELECT name,
       detected_usages,
       currently_used,
       first_usage_date,
       last_usage_date
FROM   dba_feature_usage_statistics
WHERE  detected_usages &gt; 0
ORDER  BY name;</code></pre>



<p class="wp-block-paragraph">Oracle also publishes an options and packs usage script through My Oracle Support that goes further and correlates usage across several dictionary views. If you have a support contract, use that one rather than rolling your own. The output frequently surprises people. Partitioning, Advanced Compression, and the Diagnostics and Tuning Packs get switched on by a well-meaning DBA or by a default setting and then sit there generating an entitlement gap.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Amazon RDS for Oracle: where it wins and where it hurts</h2>



<h3 class="wp-block-heading">Where RDS wins</h3>



<ul class="wp-block-list">
<li><strong>The operational floor is done for you.</strong> Automated backups with point-in-time recovery, minor version patching in a maintenance window, Multi-AZ synchronous standby with automatic failover, storage autoscaling. None of that needs a person on a rota.</li>



<li><strong>License Included removes the Oracle relationship entirely.</strong> For an SE2 workload where you own no licenses, this is genuinely hard to beat. There is no entitlement to track, no support renewal to chase, and no Oracle audit surface for the database software.</li>



<li><strong>Read replicas are configured for you.</strong> RDS manages the Data Guard setup behind cross-region replicas, including the network path between primary and standby. If the replica runs open read-only, that is Active Data Guard and you need the license for it, but the plumbing is not your problem.</li>



<li><strong>Parameter groups make configuration reviewable.</strong> Database parameters live in a versioned object you can diff, rather than in a spfile someone edited at two in the morning.</li>
</ul>



<h3 class="wp-block-heading">Where RDS hurts</h3>



<p class="wp-block-paragraph">The master user on an RDS for Oracle instance gets the DBA role with pieces removed. AWS documents exactly which privileges are withheld to keep the managed experience intact:</p>



<ul class="wp-block-list">
<li><code>ALTER DATABASE</code></li>



<li><code>ALTER SYSTEM</code></li>



<li><code>CREATE ANY DIRECTORY</code> and <code>DROP ANY DIRECTORY</code></li>



<li><code>GRANT ANY PRIVILEGE</code> and <code>GRANT ANY ROLE</code></li>
</ul>



<p class="wp-block-paragraph">You also cannot log in as <code>SYS</code>, <code>SYSTEM</code>, or any other Oracle-supplied administrative account. This is the wall most migrations hit, and they hit it late. A packaged vendor application ships an installer that expects to connect as sysdba, create a directory object pointing at a local path, and run <code>ALTER SYSTEM</code> a dozen times. On RDS that installer does not complete. There is no workaround, because the privilege is not withheld by policy, it is withheld by design.</p>



<p class="wp-block-paragraph">Three more constraints that bite later rather than sooner:</p>



<ul class="wp-block-list">
<li><strong>Block size is fixed at creation.</strong> RDS for Oracle instances are created with an 8 KB default block size and it cannot be changed afterwards. The SYSTEM and temporary tablespaces always use it. You can create additional tablespaces at other block sizes by allocating the matching cache parameter and using the <code>BLOCKSIZE</code> clause, but the core of the database is fixed.</li>



<li><strong>Single files cap at 16 TiB.</strong> That is the ext4 filesystem limit on the underlying host, so bigfile data files inherit it. Try to grow past it and you get an ORA-01237 with a &#8220;File too large&#8221; error underneath.</li>



<li><strong>No host access at all.</strong> No shell, no third-party backup agent, no monitoring agent installed on the database server, no custom scripts on the filesystem. If your compliance tooling or your APM vendor requires an on-host agent, that requirement decides the platform for you.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Oracle on EC2: where it wins and where it hurts</h2>



<h3 class="wp-block-heading">Where EC2 wins</h3>



<ul class="wp-block-list">
<li><strong>Full sysdba and full root.</strong> Everything the vendor installer wants is available. Directory objects, external tables reading from local paths, custom PL/SQL that shells out, agents, whatever the packaged application assumed about its host.</li>



<li><strong>The full replication toolbox.</strong> Data Guard, Active Data Guard, and GoldenGate all run natively on EC2, and you control the protection mode, the apply lag tolerance, and the failover behaviour rather than accepting a managed default.</li>



<li><strong>Instance shape is a license lever.</strong> This is the underrated one. Oracle bills you on vCPUs, and most Oracle databases are memory bound rather than thread bound. On EC2 you can pick a memory-dense family and hit your SGA target without buying vCPUs, and therefore licenses, that the workload never uses. RDS gives you a narrower catalogue to choose from.</li>



<li><strong>You choose when to patch.</strong> No maintenance window imposed from outside, no forced minor version upgrade, no surprise reboot on a night your business cannot take one.</li>



<li><strong>Storage is yours to shape.</strong> Separate EBS volumes for data, redo, and archive logs, with independent IOPS and throughput. RDS abstracts that away.</li>
</ul>



<h3 class="wp-block-heading">Where EC2 hurts</h3>



<p class="wp-block-paragraph">Every one of those wins is a job someone now has to do, forever. The honest cost of Oracle on EC2 is not the instance-hour, it is the rota.</p>



<ul class="wp-block-list">
<li><strong>Backups you have to prove.</strong> RMAN to S3 is a solved pattern, but a backup that has never been restored is a hypothesis. Schedule a real restore into a throwaway instance on a cadence and treat a failed restore as an incident.</li>



<li><strong>A standby that drifts silently.</strong> Data Guard apply lag is the classic invisible failure. Everything looks green, the standby is mounted, redo is shipping, and apply stopped three days ago because of a single nologging operation or a filesystem that filled. You find out during the failover.</li>



<li><strong>Patching is now a project.</strong> Quarterly Oracle patches, OS patches, and the interaction between them. On a Data Guard pair that means a standby-first sequence and a rollback plan.</li>



<li><strong>Monitoring you have to build.</strong> Tablespace growth, apply lag, wait events, ASM disk group headroom, archive log destination fullness. Amazon CloudWatch gets you host metrics and nothing about the database. Teams typically land on a Prometheus exporter feeding Grafana, either self-hosted or through Grafana Cloud or Amazon Managed Grafana, plus alerting that someone actually answers.</li>



<li><strong>Cost attribution gets murky.</strong> Instance, EBS, snapshots, cross-AZ traffic, and the license amortisation all land in different places. A cost visibility tool such as Vantage or CloudZero earns its keep here, because the Oracle line is the one finance will ask about.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">The middle option that is being retired</h2>



<p class="wp-block-paragraph">For a while the answer to &#8220;I need sysdba but I also want managed backups&#8221; was Amazon RDS Custom for Oracle. It gave you shell access to the underlying EC2 instance and sysdba on the database, while keeping automated backups and host recovery, policed by a mechanism called the support perimeter that flagged your instance as unsupported if a change broke the automation.</p>



<p class="wp-block-paragraph">AWS has announced that support for RDS Custom for Oracle ends on 31 March 2027. After that date the console and the resources go away, including instances, snapshots, and custom engine versions. AWS&#8217;s own guidance is to move those workloads to self-managed Oracle on EC2.</p>



<p class="wp-block-paragraph">This is one of the few dates worth putting in an article, because it removes an option from your decision tree. If you are choosing a platform today, RDS Custom for Oracle is not a candidate. If you are already on it, the migration is on your roadmap whether you have written it down or not. Note that this retirement does not touch RDS for Oracle or RDS Custom for SQL Server.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">The cost levers that actually move the number</h2>



<p class="wp-block-paragraph">Once you accept that the platform choice does not change the license rate, these are the things that do change the bill.</p>



<ol class="wp-block-list">
<li><strong>Memory-to-vCPU ratio.</strong> Reaching a memory target by moving up within a general purpose family buys vCPUs you did not need, and each pair of them is another Processor license. Picking a memory-optimised family instead is often the largest single saving available.</li>



<li><strong>Multi-AZ under BYOL doubles the count.</strong> AWS states this plainly in its own documentation: under BYOL you must have a license for both the primary and the standby DB instance in a Multi-AZ deployment. Enabling the checkbox on a BYOL instance without buying the second set of licenses puts you out of compliance the moment it comes up.</li>



<li><strong>Options and management packs.</strong> These are priced per Processor on top of the database license. On RDS, option groups can put some of them one click away, which is convenient and expensive in equal measure.</li>



<li><strong>Edition, forced by the vCPU ceiling.</strong> SE2 stops at eight vCPUs in an Authorized Cloud Environment. A workload that needs more compute has to move to Enterprise Edition, and that is a different order of magnitude, not a percentage increase.</li>



<li><strong>Infrastructure commitments.</strong> Reserved Instances and Savings Plans reduce the AWS side of the bill on both platforms. They do nothing to the Oracle side.</li>
</ol>



<p class="wp-block-paragraph">Two quick checks worth running before you model anything. First, confirm what an instance is actually presenting, because the multi-threading state is what decides whether you divide by two:</p>



<pre class="wp-block-code"><code># On an EC2 instance: threads per core tells you the multi-threading state.
# "Thread(s) per core: 2" means the 2 vCPU = 1 Processor rule applies.
lscpu | grep -E 'Thread(s) per core|Core(s) per socket|^CPU(s):'</code></pre>



<p class="wp-block-paragraph">Second, check what your existing RDS instances are declaring, since the license model and the Multi-AZ flag together determine your exposure:</p>



<pre class="wp-block-code"><code># Every Oracle RDS instance with its class, license model and Multi-AZ state.
aws rds describe-db-instances 
  --query "DBInstances[?starts_with(Engine, 'oracle')].
[DBInstanceIdentifier,Engine,DBInstanceClass,LicenseModel,MultiAZ]" 
  --output table</code></pre>



<p class="wp-block-paragraph">A <code>MultiAZ</code> value of <code>true</code> next to a <code>LicenseModel</code> of <code>bring-your-own-license</code> is the line to look at twice.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">How I would decide between Oracle on EC2 vs RDS</h2>



<p class="wp-block-paragraph">Run these in order. The first question that returns a hard &#8220;no&#8221; makes the decision for you, and you can stop.</p>



<ol class="wp-block-list">
<li><strong>Does anything need sysdba or host access?</strong> Vendor installers, on-host agents, directory objects pointing at local paths, external tables reading local files, custom OS-level jobs. If yes, it is EC2. Nothing else in this list matters.</li>



<li><strong>Run the feature usage query.</strong> Establish which options and packs you are on the hook for today. That number travels with you regardless of platform, and it is usually larger than the team expects.</li>



<li><strong>Check the physical constraints.</strong> Non-8 KB block size on the SYSTEM tablespace, or a single data file heading past 16 TiB, both rule RDS out.</li>



<li><strong>Settle the edition.</strong> If SE2 fits inside eight vCPUs and you own no perpetual licenses, RDS with License Included is very hard to argue against. If you need Enterprise Edition, you are BYOL on either platform and the licensing argument is over.</li>



<li><strong>Count licenses at the shape you would really run.</strong> Production instance, plus standby if you want Multi-AZ or Data Guard, plus every option pack from step two. Do this before you look at instance-hour rates, because it is the bigger number.</li>



<li><strong>Price the rota honestly.</strong> Who runs restore tests, who owns the patch calendar, who gets paged at three in the morning when apply lag alerts. If the answer is &#8220;we will figure it out,&#8221; that is a vote for RDS.</li>



<li><strong>Pick, then write down why.</strong> Record the Oracle policy version you counted against and the instance shapes you assumed. When an audit letter arrives, that document is the difference between a conversation and a negotiation.</li>
</ol>



<p class="wp-block-paragraph">One useful side effect of building a dev or reporting copy outside AWS entirely: a modest VPS from a provider like Contabo or InterServer running Oracle&#8217;s free Express Edition gives developers a schema to work against without touching a licensed instance. It will not stand in for production, but it takes pressure off the environments that cost money.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Arguments that do not survive contact</h2>



<ul class="wp-block-list">
<li><strong>&#8220;RDS is cheaper because AWS manages it.&#8221;</strong> Under BYOL the license line is identical. What you save is operational labour, which is a real saving but a different budget line, and you should say which one you mean.</li>



<li><strong>&#8220;We will disable multi-threading to reduce licenses.&#8221;</strong> Turning it off halves your usable threads and flips the ratio to one vCPU per Processor license. You end up at the same license count with less compute.</li>



<li><strong>&#8220;The core factor gives us 0.5 on x86.&#8221;</strong> Not in an Authorized Cloud Environment. Oracle states the table does not apply there. This is the source of the widely repeated claim that moving to the cloud doubles Oracle licensing on identical hardware.</li>



<li><strong>&#8220;The standby is passive, so it is free.&#8221;</strong> AWS documents that BYOL Multi-AZ requires licensing both instances. There is a separate Oracle provision about genuinely cold failover nodes, but a synchronous standby that is always running is not that. Get your specific position confirmed in writing by whoever advises you on Oracle contracts, not from a blog, including this one.</li>



<li><strong>&#8220;Graviton is a different architecture, so it licenses differently.&#8221;</strong> The cloud policy counts vCPUs. It does not carve out processor architectures on shared tenancy.</li>



<li><strong>&#8220;We will start on RDS and move to EC2 if it does not work.&#8221;</strong> Technically true and practically expensive. Moving off RDS means a full migration project with a cutover window, not a configuration change. Establish the sysdba requirement before you build, not after.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Frequently asked questions</h2>



<h3 class="wp-block-heading">Is Oracle licensing cheaper on RDS than on EC2?</h3>



<p class="wp-block-paragraph">Under bring-your-own-license, no. Oracle&#8217;s cloud policy names EC2 and RDS together and applies the same vCPU counting to both. The only structural difference is that RDS offers a License Included model, which is available for Standard Edition 2 only.</p>



<h3 class="wp-block-heading">Can I run Oracle Enterprise Edition with License Included on RDS?</h3>



<p class="wp-block-paragraph">No. AWS supports License Included for Standard Edition 2 only. Enterprise Edition on RDS is BYOL, and you need the appropriate licenses with active Software Update License and Support.</p>



<h3 class="wp-block-heading">Do I need to license the Multi-AZ standby?</h3>



<p class="wp-block-paragraph">Under BYOL, AWS documentation states you must have a license for both the primary and the standby DB instance. Budget for double the Processor count before you enable it. Under License Included the standby is reflected in the instance-hour rate instead.</p>



<h3 class="wp-block-heading">What is the largest Standard Edition 2 instance I can run on AWS?</h3>



<p class="wp-block-paragraph">Oracle&#8217;s cloud policy caps Standard Edition 2 at eight AWS vCPUs. Past that you are into Enterprise Edition. This ceiling catches a lot of migrations that were sized on memory requirements rather than vCPU count.</p>



<h3 class="wp-block-heading">Can I get sysdba access on RDS for Oracle?</h3>



<p class="wp-block-paragraph">No. The master user receives the DBA role minus a documented set of privileges including <code>ALTER SYSTEM</code>, <code>ALTER DATABASE</code>, <code>CREATE ANY DIRECTORY</code>, and the <code>GRANT ANY</code> privileges, and the Oracle-supplied administrative accounts are not available for login. If an application requires sysdba, EC2 is your platform.</p>



<h3 class="wp-block-heading">Is RDS Custom for Oracle still a viable middle ground?</h3>



<p class="wp-block-paragraph">Not for new work. AWS ends support for RDS Custom for Oracle on 31 March 2027 and recommends moving those workloads to EC2. Existing users should treat the migration as a scheduled project rather than a future problem.</p>



<h3 class="wp-block-heading">Does turning off hyperthreading reduce my Oracle license count?</h3>



<p class="wp-block-paragraph">No. With multi-threading enabled the ratio is two vCPUs per Processor license. With it disabled the ratio becomes one to one. The license requirement stays where it was while your available compute halves.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">If you remember one thing from the Oracle on EC2 vs RDS comparison, make it this: the platform choice does not change what Oracle charges you. It changes who does the work and what your application is allowed to do.</p>



<p class="wp-block-paragraph">So run the decision in that order. Establish the sysdba requirement first, because it is binary and it ends the discussion. Count your options and packs second, because that number is usually wrong in the direction that costs money. Compare instance-hour rates last, because it is the smallest term in the equation and the one everyone starts with.</p>



<p class="wp-block-paragraph">And write down which version of Oracle&#8217;s cloud policy you counted against. It is a non-contractual document that can change, and the copy you filed on the day you deployed is worth more than any argument you can make from memory later.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Need a second pair of eyes on an Oracle migration to AWS?</h2>



<p class="wp-block-paragraph">Most of the expensive mistakes here happen before anything is built, in the assumptions nobody wrote down. Things I can help with:</p>



<ul class="wp-block-list">
<li>Auditing feature and option pack usage on your existing databases so you know your real entitlement position before you size anything</li>



<li>Working through the sysdba and host-access requirements of packaged applications to determine whether RDS is even on the table</li>



<li>Modelling Processor counts across candidate instance shapes, including standby and Multi-AZ exposure, so the number in the business case survives review</li>



<li>Building the operational layer that self-managed Oracle on EC2 needs: RMAN to S3, tested restores, Data Guard apply-lag alerting, and patch runbooks</li>



<li>Planning migrations off RDS Custom for Oracle to EC2 ahead of the end-of-support date</li>



<li>Setting up monitoring and cost attribution that separates the AWS line from the Oracle line, so finance gets an answer instead of a total</li>
</ul>



<p class="wp-block-paragraph">Send me the output of your feature usage query, or a list of the instance classes you are considering, and I will tell you what I would check first.</p>



<div class="wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="https://www.upwork.com/freelancers/~01f15a912ad84a6620" target="_blank" rel="noreferrer noopener">Work with me on Upwork</a></div>
</div>
<p>The post <a href="https://john-nessime.com/blog/technical-guides/oracle-on-ec2-vs-rds/">Oracle on EC2 vs RDS: Why the License Math Doesn&#8217;t Save You</a> appeared first on <a href="https://john-nessime.com/blog">John Nessime</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Choosing an AWS Region for a MENA Client: Latency Is the Last Question</title>
		<link>https://john-nessime.com/blog/cloud-computing/aws-region-for-mena/</link>
		
		<dc:creator><![CDATA[John Nessime]]></dc:creator>
		<pubDate>Wed, 26 Aug 2026 09:00:00 +0000</pubDate>
				<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Compliance]]></category>
		<category><![CDATA[Amazon CloudFront]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[AWS Control Tower]]></category>
		<category><![CDATA[AWS Regions]]></category>
		<category><![CDATA[Cross-Border Data Transfer]]></category>
		<category><![CDATA[Data Residency]]></category>
		<category><![CDATA[Data Transfer Costs]]></category>
		<category><![CDATA[Disaster Recovery]]></category>
		<category><![CDATA[MENA]]></category>
		<category><![CDATA[Multi-AZ]]></category>
		<category><![CDATA[Parameter Store]]></category>
		<category><![CDATA[PDPL]]></category>
		<category><![CDATA[Region Selection]]></category>
		<category><![CDATA[Service Control Policies]]></category>
		<guid isPermaLink="false">https://john-nessime.com/blog/?p=548</guid>

					<description><![CDATA[<p>Latency is the constraint everyone reaches for first when choosing an AWS region for MENA clients, and it is almost always the one that matters least. Residency law eliminates candidates, service availability eliminates more, and latency only picks between whatever survives. A practical walkthrough of that filter, with the commands to check service availability and region opt-in status programmatically, the guardrail that keeps the decision true, and the things that break in the first few weeks after you commit.</p>
<p>The post <a href="https://john-nessime.com/blog/cloud-computing/aws-region-for-mena/">Choosing an AWS Region for a MENA Client: Latency Is the Last Question</a> appeared first on <a href="https://john-nessime.com/blog">John Nessime</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Someone says it on the kickoff call, usually in the first ten minutes. &#8220;Bahrain, right? It&#8217;s the closest one.&#8221; Everybody nods, the Terraform gets written, and six weeks later the client&#8217;s lawyer asks a question nobody prepared for: where exactly is the personal data of our Egyptian users sitting right now?</p>



<p class="wp-block-paragraph">That is the moment the region choice stops being a performance question and turns into an expensive one. Choosing an AWS region for MENA workloads looks like a latency problem and almost never is. Latency is the constraint you can measure in an afternoon and fix with a CDN. Residency is the constraint that can force you to rebuild.</p>



<p class="wp-block-paragraph">This post walks through the order I work in when picking an AWS region for MENA clients: which constraints bind hard, which ones bend, how to check service availability programmatically instead of trusting a table someone screenshotted, and what tends to break after the decision is made.</p>



<h2 class="wp-block-heading">Work the constraints in the order they bind</h2>



<p class="wp-block-paragraph">Region selection is a filter, not a scoring exercise. You are not hunting for the best average across four categories. You are eliminating regions that cannot work, in the order that matters, then picking from whatever survives.</p>



<p class="wp-block-paragraph">The order I use:</p>



<ol class="wp-block-list">
<li><strong>Residency and regulatory obligations.</strong> Not engineerable. Either the law permits the data to sit there or it does not.</li>



<li><strong>Service availability.</strong> Not engineerable cheaply. If the region lacks something your design needs, you change the design or change the region.</li>



<li><strong>Resilience and blast radius.</strong> Partly engineerable, bounded by which regions are near enough to pair with.</li>



<li><strong>Latency.</strong> Very engineerable. Edge caching, connection reuse and smaller payloads beat a few hundred kilometres of fibre most of the time.</li>
</ol>



<p class="wp-block-paragraph">Most guides run this list backwards, because latency is the fun part and the one with a nice map. Running it backwards is how you end up with a beautifully fast architecture that legal makes you move.</p>



<h2 class="wp-block-heading">Constraint one: residency, and the region that does not exist</h2>



<p class="wp-block-paragraph">Here is the thing that catches people who have only worked with EU or US clients. In Europe you can usually satisfy a residency requirement by picking a region in the right country. Across MENA, that option frequently is not on the table, because AWS does not have an infrastructure region in most MENA countries.</p>



<p class="wp-block-paragraph">Check the current region table before you promise anything. The list changes, and the geography column is what a regulator cares about, not the region&#8217;s marketing name. The programmatic version:</p>



<pre class="wp-block-code"><code># List every region your account can see, with opt-in status
aws account list-regions 
  --query 'Regions[*].[RegionName,RegionOptStatus]' 
  --output table

# Confirm the physical country AWS records for a region
aws ssm get-parameters-by-path 
  --path /aws/service/global-infrastructure/regions/me-central-1 
  --region us-east-1 
  --output table</code></pre>



<p class="wp-block-paragraph">That second command returns the metadata AWS publishes for the region, including a geolocation country code. Better source than a blog post, this one included, because it comes from the same data the console uses.</p>



<p class="wp-block-paragraph">One caution on the path itself: the <code>global-infrastructure</code> parameter tree is only queryable from a subset of regions, so pin <code>--region us-east-1</code> on those calls rather than assuming your default profile region will work.</p>



<h3 class="wp-block-heading">Announced is not the same as available</h3>



<p class="wp-block-paragraph">AWS announces regions well ahead of general availability, and those announcements get quoted back at you by sales teams and clients as though the capacity already exists. Treat an announcement as a roadmap item. If the region code does not appear in the table your account can query, you cannot deploy to it, and you certainly cannot write a residency clause around it. That gap matters in the Gulf specifically, where announced-but-not-yet-open regions have been part of the conversation for a while.</p>



<h3 class="wp-block-heading">Residency and localisation are not the same requirement</h3>



<p class="wp-block-paragraph">The word &#8220;residency&#8221; gets used for at least three different obligations, and clients rarely distinguish between them. Before you look at a single region, get the client&#8217;s counsel to tell you which one applies:</p>



<ul class="wp-block-list">
<li><strong>Hard localisation.</strong> The data must sit in-country, full stop. With no region in that country, no AWS region satisfies this and you are into a local provider, on-premises kit, or a hybrid split.</li>



<li><strong>Conditional transfer.</strong> Data may leave if a condition is met: regulator authorisation, an adequacy finding, explicit consent, a specific contractual basis. This is the common case, and it is more paperwork problem than architecture problem.</li>



<li><strong>Sector rules on top.</strong> Finance, health and government workloads usually add a supervisor with its own cloud rules, which may name approved jurisdictions or require notice before you move anything.</li>
</ul>



<p class="wp-block-paragraph">Egypt is the clearest illustration of why this matters to an engineer. Its Personal Data Protection Law and the executive regulations under it set up a regime where moving personal data out of the country generally needs a licence or permit from the supervisory authority, rather than a self-assessment you document internally and move on from. There is no AWS region in Egypt. So for an Egyptian client with personal data in scope, picking a region does not answer the residency question. It restates it: which foreign region will we be authorised to transfer into, and who is filing that application?</p>



<p class="wp-block-paragraph">I am not a lawyer and neither are you. What you can do is refuse to let the region be chosen before that answer exists, because picking first and asking later is how the rebuild happens.</p>



<h3 class="wp-block-heading">Enforce the decision in the account, not in the runbook</h3>



<p class="wp-block-paragraph">Once the approved regions are settled, stop treating them as a convention. A convention survives until someone opens the console in the wrong region at eleven at night.</p>



<p class="wp-block-paragraph">The mechanism is the <code>aws:RequestedRegion</code> condition key, applied either as an IAM policy or, better, as a Service Control Policy across the organisation so it cannot be edited away by an account admin. AWS Control Tower ships a managed version of the same idea as its Region deny control if you are running a landing zone.</p>



<pre class="wp-block-code"><code>{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyOutsideApprovedRegions",
      "Effect": "Deny",
      "NotAction": [
        "cloudfront:*",
        "iam:*",
        "organizations:*",
        "route53:*",
        "support:*"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": [
            "me-central-1"
          ]
        }
      }
    }
  ]
}</code></pre>



<p class="wp-block-paragraph">The <code>NotAction</code> block is the part people get wrong, and it is worth understanding rather than copying. Several AWS services are global with a single control-plane endpoint that lives in <code>us-east-1</code>. A blanket deny on everything outside your approved region catches those calls too, and locks you out of IAM. Exempting them by action prefix is what keeps the policy usable. Extend the list to match what the client actually runs, and test it in a sandbox account before it goes anywhere near production.</p>



<p class="wp-block-paragraph">One wrinkle worth checking: managed inference services can route requests to other regions within a geography to absorb load. Sensible availability feature, simultaneous residency problem. If generative AI is in scope, confirm the routing behaviour explicitly rather than assuming a request to a regional endpoint stays there.</p>



<h2 class="wp-block-heading">Constraint two: service availability, where the nasty surprises live</h2>



<p class="wp-block-paragraph">Not every AWS service exists in every region, and the gap is widest in the newest and smallest ones. This is the failure mode that bites hardest, because it is invisible during design and obvious during implementation. The diagram gets approved, the Terraform plan runs, and one resource type throws an error that reads like a permissions problem but is really a &#8220;this does not exist here&#8221; problem.</p>



<p class="wp-block-paragraph">Do not check this against the services page by eye. Check it in a script, at design time, against the same source AWS uses:</p>



<pre class="wp-block-code"><code># Is a given service available in a given region?
# An empty result means no.
aws ssm get-parameters-by-path 
  --path /aws/service/global-infrastructure/services/athena/regions/me-central-1 
  --region us-east-1 
  --output text

# Every service AWS records for a region
aws ssm get-parameters-by-path 
  --path /aws/service/global-infrastructure/regions/me-central-1/services 
  --region us-east-1 
  --query 'Parameters[].Name' 
  --output text

# The canonical list of service identifiers to test against
aws ssm get-parameters-by-path 
  --path /aws/service/global-infrastructure/services 
  --region us-east-1 
  --query 'Parameters[].Name | sort(@)' 
  --output text</code></pre>



<p class="wp-block-paragraph">The identifiers in that tree are short API names, not display names, which trips people up. Pull the full list and grep it rather than guessing how a service name is spelled.</p>



<p class="wp-block-paragraph">Two refinements make this useful rather than a party trick:</p>



<ul class="wp-block-list">
<li><strong>Write the check as a matrix, not a lookup.</strong> Put the services your design depends on in a file, loop over the candidate regions, print a grid. You want the gaps visible before any infrastructure code exists.</li>



<li><strong>Presence is not feature parity.</strong> The parameter tree says a service exists in a region. It says nothing about which instance families, engine versions, storage classes or model options are offered there, and newer regions routinely carry a narrower menu. Where the specific variant matters, check that service&#8217;s own regional documentation too.</li>
</ul>



<h3 class="wp-block-heading">Opt-in regions and the quiet failures they cause</h3>



<p class="wp-block-paragraph">Every AWS region introduced in recent years, including all of the Middle East regions, is disabled by default and must be enabled on the account before you can use it. Small piece of admin, disproportionate number of confusing failures.</p>



<p class="wp-block-paragraph">The failure shape is always the same: it works in your account and fails in the client&#8217;s, or works in the management account and fails in a member account created last week. Enablement is per-account and not instantaneous, so any automated account vending process has to handle it.</p>



<pre class="wp-block-code"><code>aws account get-region-opt-status --region-name me-central-1</code></pre>



<p class="wp-block-paragraph">Run that against every account in scope as a pre-flight check, not as a debugging step after a pipeline fails.</p>



<h2 class="wp-block-heading">Constraint three: resilience and concentration risk</h2>



<p class="wp-block-paragraph">Every AWS region carries at least three Availability Zones, and the Middle East regions are three-AZ regions. That is enough for a properly designed multi-AZ deployment, and multi-AZ should be your default for anything the client would notice going down.</p>



<p class="wp-block-paragraph">The subtlety is what you pair the region with. Cross-region DR inside MENA pairs two regions that sit closer together than a European or North American pair would, and that share more exposure to the same events: a cut on a common submarine route, a regulatory action, a physical incident. That is not an argument against a MENA pair. It is an argument for saying plainly what the DR plan protects against, because a nearby second region covers a regional AWS failure and not much wider than that.</p>



<p class="wp-block-paragraph">Two practical points on AZ handling that catch people:</p>



<ul class="wp-block-list">
<li><strong>AZ names are per-account.</strong> The letter suffix on a zone name does not map to the same physical zone across two different accounts. If you are coordinating placement between accounts, use the zone ID rather than the name. <code>aws ec2 describe-availability-zones --region me-central-1</code> returns both.</li>



<li><strong>Capacity is not uniform.</strong> Smaller regions have less headroom in specific instance families, and you can hit an insufficient-capacity error on a launch that would have succeeded in a large region. Design for instance-family flexibility, and if the workload is steady state, talk to the client about a capacity commitment rather than discovering the ceiling during a launch window.</li>
</ul>



<h2 class="wp-block-heading">Constraint four: latency, finally</h2>



<p class="wp-block-paragraph">By the time residency and service availability have done their work you often have one candidate left, and the latency question answers itself. When you do still have a choice, measure properly.</p>



<p class="wp-block-paragraph">Measuring from your own machine tells you about your own connection, which is not what you care about. Regional routing is often counter-intuitive, and traffic between two Gulf cities does not necessarily take the short path. You want a measurement from the network the users are actually on. Options, in rough order of how much I trust them:</p>



<ul class="wp-block-list">
<li><strong>Real user monitoring on an existing property.</strong> If the client already has a site or app with users in that market, instrument it and read the field data. Nothing synthetic beats this.</li>



<li><strong>A small instance in each candidate region, probed from the target country.</strong> Cheap, quick, measures the actual path rather than a claim about it.</li>



<li><strong>A commercial VPN endpoint in the target country</strong> when you have no presence there. NordVPN or Surfshark will sanity-check the relative ordering of two regions, but treat the absolute numbers with suspicion: you are measuring a path through the provider&#8217;s network, not a real user&#8217;s path.</li>



<li><strong>Published latency matrices.</strong> Fine for a first pass. Not evidence.</li>
</ul>



<h3 class="wp-block-heading">Split the problem before you optimise the region</h3>



<p class="wp-block-paragraph">Most of what users experience as slowness is not round-trip time to the origin. It is uncached static assets, chatty APIs, TLS handshakes on cold connections, and payloads bigger than they need to be. A CDN fixes a large share of that whatever region the origin sits in, and the edge network is far denser across MENA than the region footprint is. Amazon CloudFront is the obvious in-stack choice; Cloudflare is worth a look when the client wants DNS, WAF and edge in one place, or when the origin is not on AWS at all.</p>



<p class="wp-block-paragraph">The caveat matters though. Caching at the edge puts copies of responses in edge locations worldwide. For static assets that is fine. For authenticated responses carrying personal data it is a residency question of its own, and the answer is usually to scope caching tightly and leave dynamic personal responses uncached.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">What breaks after you have chosen</h2>



<p class="wp-block-paragraph">A short troubleshooting list for the first few weeks, drawn from the things that reliably go wrong.</p>



<ul class="wp-block-list">
<li><strong>Access denied on a service you definitely have permissions for.</strong> Check the region deny SCP first, then check whether the call is hitting a global endpoint you forgot to exempt. The error will not tell you an SCP is responsible.</li>



<li><strong>A certificate that will not attach to your distribution.</strong> Certificates used with CloudFront must be requested in <code>us-east-1</code> regardless of where the origin lives. This looks like a residency violation to a nervous auditor and is not one, since a certificate holds no personal data. Have the explanation ready.</li>



<li><strong>Terraform plans that differ between engineers.</strong> Someone has a different default region in their profile. Pin it in the provider block and stop relying on environment configuration.</li>



<li><strong>An unexpected data transfer line on the bill.</strong> Cross-region traffic is charged, and replication, backups and cross-region reads all generate it quietly. Get cost allocation tags working before the first full month closes so you can attribute it rather than argue about it.</li>



<li><strong>A service that exists but behaves differently.</strong> Quotas start lower in newer regions and some features lag. Check the quota console before assuming your code is wrong.</li>
</ul>



<h2 class="wp-block-heading">Common mistakes</h2>



<ul class="wp-block-list">
<li>Choosing the region on the kickoff call, before anyone has asked counsel what the transfer basis is.</li>



<li>Treating proximity as the residency answer. A region in a neighbouring country is still a cross-border transfer.</li>



<li>Copying a region deny policy from a blog without adapting the global-service exemptions to the client&#8217;s real service inventory.</li>



<li>Checking service availability once at the start and never again as the design grows new components.</li>



<li>Forgetting the observability stack. Logs and metrics carry personal data more often than people expect, and a monitoring platform hosted in another jurisdiction is a transfer. Grafana Cloud and the AWS-native options both let you choose where data lands, so choose deliberately.</li>



<li>Assuming this has to be AWS at all. For a low-sensitivity workload with no compliance surface, a VPS from Contabo or InterServer may beat a thin footprint in an expensive region. Say so if it is true.</li>
</ul>



<h2 class="wp-block-heading">How I would pick an AWS region for MENA</h2>



<ol class="wp-block-list">
<li>Get the in-scope data classes in writing. Personal data, health data, financial records and anonymised telemetry carry different rules.</li>



<li>Ask counsel which residency shape applies and whether a sector supervisor sits on top. Eliminate the regions that fail it. If nothing survives, have the hybrid conversation now rather than in month four.</li>



<li>Run the availability matrix against the survivors and eliminate again. If more than one region is left, measure latency from the target country and pick.</li>



<li>Write down the choice and the reasoning, enable the region on every account in scope, and apply the guardrail that same week.</li>
</ol>



<p class="wp-block-paragraph">That last step is the one people skip. A region decision without a written rationale gets relitigated every time a new engineer joins, and a region decision without a guardrail quietly stops being true.</p>



<h2 class="wp-block-heading">Frequently asked questions</h2>



<h3 class="wp-block-heading">Which AWS region is best for a client in the UAE?</h3>



<p class="wp-block-paragraph">If in-country storage is required, the UAE region is the only AWS option that puts data inside the country. If the requirement is softer, Bahrain is a fair alternative and has been open longer, which usually means broader service coverage. Run the availability matrix against both before committing.</p>



<h3 class="wp-block-heading">Is there an AWS region in Egypt or Saudi Arabia?</h3>



<p class="wp-block-paragraph">Check the region table rather than trusting any article, this one included. AWS has publicly announced intent to build in the area and those announcements circulate widely, but only regions appearing in the table your account can query are deployable. Where there is no region, the real question is which nearby region you are permitted to transfer into.</p>



<h3 class="wp-block-heading">Does choosing a nearby AWS region satisfy MENA data residency law?</h3>



<p class="wp-block-paragraph">Not by itself. Several MENA data protection regimes treat any movement of personal data across national borders as a transfer needing a legal basis, and some require prior authorisation from a regulator. Geographic closeness carries no legal weight. Get the transfer basis confirmed before the region is fixed.</p>



<h3 class="wp-block-heading">How do I check whether a specific AWS service is available in a region?</h3>



<p class="wp-block-paragraph">Query the global infrastructure tree in Systems Manager Parameter Store. An empty result for a service and region pair means it is not offered there. It is the most reliable programmatic source, but it only tells you the service exists, not which features or instance types are available.</p>



<h3 class="wp-block-heading">Why do I get access denied in a Middle East region even as an administrator?</h3>



<p class="wp-block-paragraph">Two likely causes: the region is opt-in and has not been enabled on that account, or an SCP is denying requests outside an approved region list. Administrator permissions do not override an SCP, which is rather the point of one.</p>



<h3 class="wp-block-heading">How hard is it to change region later?</h3>



<p class="wp-block-paragraph">Harder than a move between accounts and much harder than people estimate. Every region-scoped identifier changes, stateful services need a data move with a cutover, and any regional endpoint baked into client configuration has to be coordinated. Budget it as a project, not a task. Which is exactly why the upfront decision deserves the care.</p>



<h2 class="wp-block-heading">The one thing worth remembering</h2>



<p class="wp-block-paragraph">Choosing an AWS region for MENA clients is a legal decision with a technical implementation, not the reverse. Residency eliminates candidates, service availability eliminates more, latency picks between whatever survives. Run the filter in that order and you will sometimes land on a region that is not the closest one, which is fine. Run it backwards and you get a fast architecture in the wrong jurisdiction, which no amount of edge caching fixes.</p>



<p class="wp-block-paragraph">Get the transfer basis in writing, enforce the decision with a guardrail rather than a convention, and record why you chose what you chose.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Need help choosing or defending a region decision?</h2>



<p class="wp-block-paragraph">This is the kind of work where an outside opinion early saves a rebuild later. Things I can help with:</p>



<ul class="wp-block-list">
<li>Running a service availability matrix across candidate regions for your actual architecture, so the gaps surface before any infrastructure code is written</li>



<li>Writing and testing a region deny SCP with the global-service exemptions tuned to your service inventory, without locking anyone out</li>



<li>Building a repeatable latency measurement from your target markets rather than from a vendor&#8217;s map</li>



<li>Designing the CDN and caching split so static content goes to the edge and personal data does not</li>



<li>Reviewing an existing deployment for accidental cross-region data flows in backups, replication, logging and monitoring</li>



<li>Producing the written region rationale your client&#8217;s auditor or counsel is going to ask for</li>
</ul>



<p class="wp-block-paragraph">Send me the architecture diagram, a Terraform provider block, or the output of your region opt-in check, and I will tell you what I would look at first.</p>



<div class="wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="https://www.upwork.com/freelancers/~01f15a912ad84a6620" target="_blank" rel="noreferrer noopener">Work with me on Upwork</a></div>
</div>
<p>The post <a href="https://john-nessime.com/blog/cloud-computing/aws-region-for-mena/">Choosing an AWS Region for a MENA Client: Latency Is the Last Question</a> appeared first on <a href="https://john-nessime.com/blog">John Nessime</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
