Itanium also had fixed-sized instructions, or more accurately, fixed-sized bundles, where each bundle encodes three instructions. Fixed-size bundles mean that, like AArch64, there is no hot-patching restriction on the first instruction of a function.
In fact, there was no spare space for hot-patching at all.
Because none was needed.
During hot-patching, the first bundle of the instruction could be overwritten with
nop
brl.cond.sptk target64
The second instruction brl is a “long branch” that accepts a 64-bit target.¹ This is a “double-wide” instruction that takes up two slots in the bundle, which is why we see a bundle of only two instructions.
Based on my experience with AArch64, I thought at first that the instruction sequence would be more like
But then I realized that this doesn’t work because you cannot perform an indirect jump through a general-purpose register. You have to move it to a branch register first. and that would take us to four instructions (since the movl occupies two slots), which exceeds the capacity of a bundle.
Bonus chatter: If you study some old Itanium binaries like I did, you will find that many functions are preceded by an apparent spare bundle:
break.m 0
break.i 0
break.i 0
This is a bundle full of breakpoint instructions, and you might be tricked (like me) into thinking that they are there for hot-patching. But then you find that some other functions don’t have this spare bundle, and after closer study, you realize that this spare bundle is not for hot patching. It’s padding to bring the start of every function to a 32-byte boundary.
¹ Formally, it’s a conditional long branch instruction predicated on p0, and statically predicted to be taken. The p0 register is hard-wired to true, so the assembler conveniently simplifies the disassembly and omits the p0.
This tutorial shows how common Elasticsearch search requests can be expressed using Azure Cosmos DB query patterns. Some Elasticsearch capabilities map directly to Cosmos DB full-text search functions, while others require separate queries or application-layer handling. Each step shows the closest Cosmos DB pattern and explains what changes in the process.
In Elasticsearch, one search request can return hits, highlights, and aggregation buckets together. In Azure Cosmos DB, it is clearer to separate those concerns: one query retrieves ranked results, separate aggregate queries calculate facets, and the application handles presentation features such as highlighting.
Step 1: Translate the ranked result query
Start with an Elasticsearch multi_match query for “shoes” across title, description, brand, and category. The request returns the first 20 hits.
SELECT *
FROM c
WHERE (
FullTextContains(c.title, 'shoes')
OR FullTextContains(c.description, 'shoes')
OR FullTextContains(c.brand, 'shoes')
OR FullTextContains(c.category, 'shoes')
)
ORDER BY RANK FullTextScore(c.title, ['shoes'])
OFFSET 0 LIMIT 20
This translation focuses on the core search behavior rather than an exact one-to-one mapping of every Elasticsearch construct. In Elasticsearch, title3 and brand2 are field boosts that make matches in the title and brand fields more influential in relevance scoring. The Azure Cosmos DB query shown here does not replicate those boost factors because field boosting is not currently supported in Azure Cosmos DB for NoSQL full-text search. Instead, results are ranked using the built-in BM25-based full-text scoring model. As a result, the returned result set and ranking order will differ from Elasticsearch when field boosts contribute to relevance. However, the BM25 scoring model is still designed to surface relevant matches first, so users can expect relevant results even though the ranking behavior is not identical.
Step 2: Split categorical facets into aggregate queries
The Elasticsearch query returns categories, subcategories, and brands as aggregation buckets in a single request.
In Azure Cosmos DB, run one aggregate query for each field. Each query repeats the result query’s text predicate and returns a facet key with a count.
SELECT
c.category AS facetKey,
COUNT(1) AS facetCount
FROM c
WHERE (
FullTextContains(c.title, 'shoes')
OR FullTextContains(c.description, 'shoes')
OR FullTextContains(c.brand, 'shoes')
OR FullTextContains(c.category, 'shoes')
)
GROUP BY c.category
Subcategory
SELECT
c.subcategory AS facetKey,
COUNT(1) AS facetCount
FROM c
WHERE (
FullTextContains(c.title, 'shoes')
OR FullTextContains(c.description, 'shoes')
OR FullTextContains(c.brand, 'shoes')
OR FullTextContains(c.category, 'shoes')
)
GROUP BY c.subcategory
Brand
SELECT
c.brand AS facetKey,
COUNT(1) AS facetCount
FROM c
WHERE (
FullTextContains(c.title, 'shoes')
OR FullTextContains(c.description, 'shoes')
OR FullTextContains(c.brand, 'shoes')
OR FullTextContains(c.category, 'shoes')
)
GROUP BY c.brand
What changes: Instead of receiving all buckets in the result response, the application issues focused aggregate queries and combines the counts with the result list.
Step 3: Translate derived rating buckets
The Elasticsearch query creates rating facets by converting each rating to its floor value before grouping.
SELECT
FLOOR(c.rating) AS facetKey,
COUNT(1) AS facetCount
FROM c
WHERE (
FullTextContains(c.title, 'shoes')
OR FullTextContains(c.description, 'shoes')
OR FullTextContains(c.brand, 'shoes')
OR FullTextContains(c.category, 'shoes')
)
GROUP BY FLOOR(c.rating)
What changes: In Elasticsearch, the bucket value is produced by a script inside the aggregation. In Azure Cosmos DB, the derived bucket value is expressed directly in SQL using FLOOR(c.rating) and then used in both SELECT and GROUP BY. The result is the same type of facet output: one row per rating bucket, with a count of matching documents in each bucket.
Step 4: Translate price range facets
The Elasticsearch query creates fixed price ranges and returns a count for each bucket. In Azure Cosmos DB, the same result can be produced with conditional aggregate expressions: each SUM counts documents that fall into one price range.
SELECT
SUM(c.price < 25 ? 1 : 0) AS under25,
SUM(c.price >= 25 AND c.price < 50 ? 1 : 0) AS r25to50,
SUM(c.price >= 50 AND c.price < 100 ? 1 : 0) AS r50to100,
SUM(c.price >= 100 AND c.price < 200 ? 1 : 0) AS r100to200,
SUM(c.price >= 200 AND c.price < 500 ? 1 : 0) AS r200to500,
SUM(c.price >= 500 ? 1 : 0) AS over500
FROM c
WHERE (
FullTextContains(c.title, 'shoes')
OR FullTextContains(c.description, 'shoes')
OR FullTextContains(c.brand, 'shoes')
OR FullTextContains(c.category, 'shoes')
)
What changes: Elasticsearch represents price ranges as a dedicated range aggregation. In Azure Cosmos DB, each range is written as a conditional count in the SELECT clause. The query still uses the same full-text predicate as the result query, so the price buckets count only documents that match the current search. This keeps the facet counts aligned with the result list.
Price boundaries can vary by what a user searches for, so precomputing them is rarely the default solution. You can also group by a derived key such as FLOOR(c.rating). More information about faceting can be found here.
Step 5: Handle highlighting in the application
The Elasticsearch request configures highlighted fragments and mark tags for title and description.
Azure Cosmos DB does not return highlighted fragments as part of the full-text query response. To recreate this behavior, run the search query normally, then generate snippets in the application layer by locating the matched query terms in fields such as title and description and wrapping them with display markup like <mark>…</mark>.
Native hit highlighting is currently under development.
Run the translated search
Execute the result query. Use the ranked query to retrieve the current page of matching documents.
Execute the required facet queries. Run category, subcategory, brand, rating, and price aggregates for the same search state.
Apply active filters everywhere. When a user narrows the search, add that filter to the result query and to every aggregate query before refreshing the UI.
Render the experience. Display results, counts, and client-side highlights together so navigation reflects a consistent result set.
Validate behavior, not just syntax
Start with a representative set of search terms and documents, then repeat the validation with production-like data. Compare ranked results, selected filters, facet counts, page behavior, request units, and end-to-end latency. This turns the tutorial from a syntax exercise into application-level validation.
Series roadmap
This post is the third and final post in the series. In Blog 1, we introduced the overall migration path for Elasticsearch users moving to Azure Cosmos DB. In Blog 2, we looked at how Elasticsearch mappings can be translated into Azure Cosmos DB indexing and full text search configuration. In this post, we brought those concepts together by walking through how to translate an Elasticsearch Search Request into an Azure Cosmos DB query.
With these three posts, you now have a starting framework for evaluating and migrating Elasticsearch-backed search workloads to Azure Cosmos DB: understand the feature model, map your indexing configuration, and translate your query patterns. For more guidance, review the Azure Cosmos DB full text search documentation or reach out to the Azure Cosmos DB team for help with your migration scenario.
SQL Server Developer Edition is free for development and testing. It includes the features of its matching paid edition, and it’s licensed for non-production use only.
Two questions come up again and again. Which download should I pick for a demo, a class or a new project? And a week later: can we keep using it for the real app? Start with the download table below, then read the production limits before you build anything on it.
Disclaimer: I’m not a licensing expert. I’m a SQL Server person, and this post shares what Microsoft’s own pages say plus my practical experience. Licensing rules change, and they depend on your exact setup and agreement. Before you make any licensing decision, confirm it with Microsoft, your Microsoft partner or your licensing team.
SQL Server Developer Edition Download Links, Version by Version
All links below point to official Microsoft pages, and each one opened on September 30, 2026. Each download link starts a small installer that fetches the rest. Microsoft’s main SQL Server downloads page always has the current version.
The last column shows the end of extended support. After that date, regular security updates stop. Unless your deployment qualifies for Extended Security Updates, the server gets no more fixes. The rules differ by version, so read the Extended Security Updates FAQ.
SQL Server 2014 and SQL Server 2016 are not in this list on purpose. Extended support for SQL Server 2014 ended on July 9, 2024, and for SQL Server 2016 on July 14, 2026. Please don’t start new work on either one. If you still run them, plan the upgrade and test it on a supported Developer Edition.
What SQL Server Developer Edition Is
Developer Edition is the full engine with a different license. Microsoft describes it as an ideal choice for people who build and test applications. Developer Edition includes the features of its corresponding paid edition. Behavior and performance still depend on the version, configuration and hardware. It costs nothing to download or use.
SQL Server 2025 changed one thing here, and it’s a good change. There are now two Developer editions. Enterprise Developer has everything in Enterprise, like the Developer Edition we had before. Standard Developer is new and has only what Standard has. If your production server runs Standard, pick Standard Developer.
Standard Developer helps you avoid Enterprise-only features. Match your production SQL Server version too. SQL Server 2025 Standard Developer can still have features that an older Standard server lacks. A laptop on 2025 and a production server on 2019 are not the same target.
What Developer Edition Is Good For
Writing and debugging code. Stored procedures, functions, triggers and queries, with every feature turned on.
Testing. Unit tests, integration tests, performance tests and upgrade tests before a new version goes live.
Learning. Practice for interviews and certifications, and trying new features without a budget request.
Trying a restore. Restore a copy of a backup to check that it works, or to test a change against real-sized data.
Classes and workshops. Every student can install the same full engine at no cost.
The engine has no editor of its own. To write queries, install SQL Server Management Studio (SSMS), the free management tool.
Why It’s Not for Production
Microsoft’s download page says the free Developer edition is for non-production development and testing. The 2025 editions page says the same about Standard Developer. It’s licensed as a development and test system, not as a production server. The software won’t stop you, and nothing pops up to warn you. That’s why people get into trouble.
Here is my simple test. If real users or a real business depends on that server today, it’s production. A reporting server that managers open every morning is production. A “temporary” server that has been live for eight months is production too. When a server moves into that role, license it with a paid edition, or move the database to one.
If you need free SQL Server in production for a small app, look at SQL Server 2025 Express. It’s free for production use, with size and resource limits. To try a paid edition before you buy, use the SQL Server 2025 Evaluation. It runs for 180 days.
SQL Server Licensing Links
Developer Edition requires no product key, but its license permits development and testing only. Production use requires appropriate licensing. These are the pages I send people to when the conversation turns to money. Read the guidance before you buy. Core and client access rules shape the price as much as the edition does.
A guide summarizes the rules. The product terms and your own agreement are what count, so check with your licensing team before a purchase.
How to Check Which Edition You Are Running
Before you move a database anywhere, check what the server is running. This query works on every version in the table above.
SELECT SERVERPROPERTY('Edition') AS Edition,
SERVERPROPERTY('EngineEdition') AS EngineEdition,
SERVERPROPERTY('ProductVersion') AS ProductVersion,
SERVERPROPERTY('ProductMajorVersion') AS MajorVersion;
Version 17 is SQL Server 2025. Engine edition 3 covers the Enterprise family, including Enterprise Developer and Evaluation. So the Edition column is the one that shows a Developer license. See Developer on a server that customers depend on? Fix the license this week.
Moving From Developer Edition to Production
Supported installations can move from Developer to a paid edition through Setup’s Edition Upgrade option. Check your version and installation type first. Some paths have restrictions, for example on failover cluster instances. Pick the target with care. If you move to Standard, first check that the database uses no Enterprise-only features.
The easier habit is to decide on day one. Match your Developer edition and version to what production will run. Run that edition query before you touch a server you don’t know. Developer Edition is free and complete, and it saves hours. Keep it where it belongs.
SQL Server Developer Edition is not a free production server, it is a free workshop for building one.
Microsoft is aware of the “framework gap” that pushes developers to the web or other frameworks, and it just rolled out one of the biggest updates for WinUI. Today’s update adds support for TableView, chart controls, and even addresses one of the bugs that contributed to memory growth on Windows 11.
The update is Windows App SDK 2.5 Experimental, released on September 29, and it finally adds WinUI 3 TableView and Chart controls. More importantly, it includes fixes for WinUI memory growth.
If you remember, Microsoft confirmed at the Build 2026 developer conference that WinUI is Windows 11’s flagship native framework, and it’s going to catch up eventually in all areas.
It also admitted that WinUI is still a mess in some areas, and there’s a framework gap where other frameworks, even though they’re not native, have more features than WinUI.
For example, until now, you couldn’t build a WinUI app that supports TableView and Chart controls using Microsoft’s own native controls. It might not sound like a big deal unless you realize how many apps could actually use these controls
WinUI did support some of these controls through community-made efforts, but these basic features have been missing from Microsoft directly. You can’t expect a “flagship” framework to not even natively support charts, right?
In fact, WinUI was a part of a big push during the early days of Windows 11, but at some point, it started looking like the framework was dead, and even Microsoft moved some of its own apps to the web.
New Outlook and Outlook Classic in Task Manager during our June 2026 testing. Image: Windows Latest
You’ve got apps like MSN Weather or even the Start menu using web components, and its flagship products, such as Outlook and Teams, are web crap.
MSN Weather using over 1GB of RAM in our August 2026 testing. Image: Windows Latest
Microsoft is shipping the WinUI controls it promised at Build
At Build 2026, Chris Anderson from Microsoft’s Windows UI team shared the following statement:
“We have DataGrid and Charting that are up and coming that should be out relatively shortly,” Anderson said during the session. “These will be showing up in the core WinUI bits and will allow you to go after a lot more of these data-oriented scenarios.”
With Windows App SDK 2.5 Experimental, you’re getting TableView with grouping, templated group headers, sorting and filtering with column-header sort indicators, pointer and keyboard column resizing, and optional tooltips for cells and column headers.
Moreover, WinUI Chart control support has also landed in this release, and as I noted, it’s a big deal because native Windows apps have lacked some of the most basic controls enterprise developers expect out of the box. It pushed developers to other frameworks, such as Electron.
Microsoft also fixed WinUI memory growth issues
Windows Latest observed that the Windows App SDK update also has a critical fix that should reduce memory usage for some modern apps.
According to Microsoft, WinUI had a bug where memory usage could grow when apps repeatedly created visual-state storyboards or resolved static or theme resources.
And that reminds me that Microsoft made it clear that performance is one of the areas where WinUI lags, and it can do better.
“The first and foremost is performance, fundamentals, quality, fixing a lot of bugs,” Anderson said at the Build 2026 developer conference.
He also noted that WinUI can sometimes use more memory, but it’ll eventually get better because Microsoft has heavily invested in improving memory usage, and it’s necessary given the rising cost of RAM.
“On the performance side we’ve invested heavily in really improving memory usage as well as switching over to a system compositor which should yield some even better performance improvements,” Anderson said.
We’re finally seeing some of these improvements, but they’ve only landed in Windows App SDK Experimental, so users and developers won’t automatically receive the benefits immediately.
“We’ve started to integrate it into the shell at a much faster rate,” Anderson said. “And so you’re going to see a lot of the first-party features coming from Microsoft being built on top of WinUI.”
How bad is Windows 11’s app situation?
Most people do not realize how bad the state of Windows 11 apps is unless they look at Task Manager and pay close attention to the framework of the apps. Most popular apps either use Edge’s WebView-based web apps or Electron, and most have not even bothered to optimize their web crap, which makes the situation even worse.
In fact, as somebody who has been following Windows development for decades, I’ve watched native apps become web apps, then become native again, then get abandoned and go back to the web. For example, WhatsApp had a native UWP app, and even Microsoft’s Copilot had a WinUI app. Both were replaced with web-based versions that used considerably more RAM in our testing.
WhatsApp’s WebView2 version climbing from about 600MB to 1.2GB of RAM while scrolling through messages in our November 2025 test. Playback is sped up 2.5×. Video: Windows Latest
For those unfamiliar, Discord uses Electron, which packages Chromium and Node.js with the app. On the other hand, apps like New Outlook, Teams, WhatsApp, and MSN Weather use WebView2 to run the entire shell in a Microsoft Edge-powered container.
Here are some of your favourite apps and their framework:
Discord said normal usage was below 1GB, but confirmed in December 2025 that it could go above 4GB.
Funny enough, WhatsApp is that one perfect old app that was easily running with 100 individual chats and around 30 active groups with that small idle footprint. Now, it feels like a pain to use WhatsApp on the desktop.
And it’s not just WhatsApp that abandoned its native app. The irony is that Microsoft made a similar choice with Copilot when it replaced its well-built WinUI version with a web version that shipped with its own Edge package and used more resources.
The web-based Copilot app in Task Manager during our April 2026 testing. Image: Windows Latest
It makes you wonder why these developers are not picking up WinUI. Is WinUI bad, or is it because Microsoft doesn’t enforce its own framework enough? Well, I’d say WinUI has been ignored for all these years, and it wasn’t clear until March 2026 what Microsoft’s flagship framework for Windows 11 actually was.
WinUI is not close to perfect, and that’s why we’re seeing these memory-related fixes or basic features finally getting added. But when you have other alternatives like WebView or Electron, I’d go with the lesser evil, and that is WinUI.
There’s no chance Windows would go back to classic Win32 apps, which worked better, felt native, and used fewer resources than any of these frameworks. But if Microsoft wants Windows 11 apps to feel less like web pages running inside Edge, WinUI is probably the closest practical answer it has right now.
Here's a software pattern that I've found new use for in our new world of
agents. I'll motivate it with an example from build systems.
When using build systems you often write down some information that feels
redundant. For example, from the source code you can see that module A imports
from module B, but then the build system requires you to separately tell it to
build module B before building A. Why do we need to write this out, when it is
visible from the source? It is tempting to figure it out automatically, as tools
like ekam do.
The easy answer for why we don't always do this is the normal software answer of
path dependence and how software tends to be clunky. But there are also two good
reasons: information like this can be costly to gather and also can be hard to
get completely right. It can be costly if your language design you might need to
parse the whole source tree to find where a given module actually lives, as
perhaps with C++ modules.
It can be hard to get correct if there is configuration complexity; for example
in a C file with #include "config.h", it is not clear which of potentially
multiple config.h candidates it means; a tool that guesses will be hard to
predict and sometimes wrong. (Just so I'm not only picking on C, I'll add that
finding where a given import ... from 'x' in JavaScript resolves to has
surprisingly complex semantics,
and can even depend on the path of the source file.)
However, in the common case it really is often possible to automate things, and
it's not that costly. This leads us to what in my head I call the guess and
check pattern: use a tool to automatically guess, edit and/or verify the
result, and write that down as the definitive answer.
For example Gazelle updates
Bazel BUILD files from Go source. Bazel then gets to run quickly without
parsing Go source, and if Gazelle gets things wrong, you can still edit the
files. As an additional benefit, you check the result in to source control,
which means a human gets to see what actually changed, and it pins down the
result.
For another example of this pattern, consider "lock files" as used in
programming language package managers. When you npm add or cargo add etc.,
the tooling makes network requests, runs a
complex algorithm to
resolve what you meant, and writes down the result. Builds after this point can
use the lock files without looking around on the network or guessing about
versions.
I used this pattern in my Windows emulator projects. For any given Windows
function
I declare the emulator's version of the function in Rust.
To automate writing out the function's matching argument list I can
generate it from metadata published by Microsoft.
But I only need that metadata when I run the generator, and the output doesn't
need to be perfect! I can generate code that is most of the way there, because
it's fine as a human to fix up the details after. The generator can even just
make up type names that don't exist because the compiler will catch it
afterwards.
Another way to look at this pattern is to see there's a chain of work to
guarantee determinism atop a nondeterministc start: you can use a tool that
makes a guess, and as long as you write down that guess and use deterministic
steps from that written state onward you still have determinism in the result.
Which finally leads me to one way I've been tentatively experimenting with AI.
AI behavior matches the shape I've been describing. An agent can do a long slow
processing step and generate some output — not limited to code, even things
like gathering data — as long as I write the output down as a result and have a
human and/or tooling verification pass after. Keeping this pattern in mind has
helped me find places where AI is suitable: problems where I know up front that
a plausible guess is all I require, and that framing helps me keep in mind that
the output is always just a guess.
(PS: just in case it wasn't obvious, my blog posts are always just me banging
away on a keyboard, no clankers will keep me from my meandering!)
Version 3.0 of SvelteKit, the official application framework for Svelte, is now available.
If you’ve used earlier versions of SvelteKit, everything will feel very familiar — it’s the same framework with a little more polish, a little more type safety, and a little less junk. We’ve made migration as seamless as we can with the sv migrate command...
npxsvmigratesveltekit-3--tasksall--confirm
...which will automatically migrate as much of your codebase as possible, and generate a TODO list for everything else. (If you’re agentically inclined, your robot friends will make short work of it.)
As with any major version bump there are a handful of breaking changes to be aware of, which are covered in the migration guide (or, more briefly, in the recent release candidate announcement).
Quick highlights:
configuration now lives in vite.config.ts instead of svelte.config.js
the $lib alias is now #lib, making use of standard subpath imports
Remote functions are a set of utilities for secure, efficient, type-safe client-server communication. You’ve likely seen some version of this idea in other frameworks, but we think you’re going to prefer this one.
Using them requires Async Svelte, which for now requires an experimental flag. Bear with us.
Join us in Ljubljana next month
This is as good a place as any to remind everyone that the next in-person Svelte Summit is taking place on November 19-20 in the lovely town of Ljubljana, Slovenia. Among other things it will be a celebration of Svelte’s 10th birthday, and we’d love to share some cake with you.