{"id":250,"date":"2026-08-11T09:00:26","date_gmt":"2026-08-11T16:00:26","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/insidemsix\/?p=250"},"modified":"2026-08-11T18:10:08","modified_gmt":"2026-08-12T01:10:08","slug":"msix-package-lifetime","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/insidemsix\/msix-package-lifetime\/","title":{"rendered":"Remove and Package Lifetime"},"content":{"rendered":"<p>MSIX uses a <strong>Garbage Collection (GC)<\/strong> design for staged package lifetime and <a href=\"https:\/\/devblogs.microsoft.com\/insidemsix\/remove-is-not-uninstall\/\">destaging<\/a>.<\/p>\n<p>Throughout this article:<\/p>\n<ul>\n<li>Remove refers to the Deployment operation requested by the caller.<\/li>\n<li>Deregister refers to removing a user&#8217;s registration for a package.<\/li>\n<li>Destage refers to removing the staged package payload from disk.<\/li>\n<\/ul>\n<h2>Package Core Principles<\/h2>\n<p>A staged package can&#8217;t be destaged while any references to it exist. This is a direct consequence of MSIX&#8217;s core architectural principles:<\/p>\n<ul>\n<li>staged packages are immutable<\/li>\n<li>staged packages are shared across users<\/li>\n<li>staged packages may satisfy dependencies for other packages<\/li>\n<\/ul>\n<p>Consequently, removing a package&#8217;s payload from disk is not a direct result of a single API call.<\/p>\n<p>Instead, package payloads are automatically destaged when they are no longer needed.<\/p>\n<p>Even then, destaging may not occur immediately.<\/p>\n<p>Some actions that remove a reference don&#8217;t directly trigger Deployment activity. In these cases, the staged package will be destaged the next time Deployment evaluates it.<\/p>\n<p>In practice, destaging usually occurs soon after the final strong reference is removed.<\/p>\n<h2>Package References<\/h2>\n<p>Packages remain staged because something references them. Some package types have additional referencing behaviors or caveats, but broadly speaking:<\/p>\n<p>References may be either <strong><em>strong<\/em><\/strong> or <strong><em>weak<\/em><\/strong>.<\/p>\n<p>Almost all types of references are <em>strong<\/em> references, and are commonly referred to simply as references.<\/p>\n<h3>Strong References<\/h3>\n<p>A package <strong>can&#8217;t<\/strong> be destaged while a strong reference to it exists.<\/p>\n<p>Forms of strong reference include:<\/p>\n<ol>\n<li><strong>&lt;<a href=\"https:\/\/learn.microsoft.com\/uwp\/schemas\/appxpackage\/uapmanifestschema\/element-f-packagedependency\">PackageDependency<\/a>><\/strong> &#8211; A dependency on a Framework package. This is sometimes referred to as a static dependency because it is defined in the package manifest when the package is built. Only Main packages can declare a (static) dependency on a Framework package. \n<ul>\n<li>Only Framework packages can satisfy a <code>&lt;PackageDependency&gt;<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li><strong>&lt;<a href=\"https:\/\/learn.microsoft.com\/uwp\/schemas\/appxpackage\/uapmanifestschema\/element-uap10-hostruntimedependency\">HostRuntimeDependency<\/a>><\/strong> &#8211; A package providing a Host Runtime may satisfy a <code>&lt;HostRuntimeDependency&gt;<\/code>. Only Main and Framework packages can participate in Host Runtime relationships.<\/li>\n<li><strong><a href=\"https:\/\/devblogs.microsoft.com\/insidemsix\/msix-per-user-vs-all-users\/\">Provisioned<\/a><\/strong> &#8211; A package is provisioned for users on the system.<\/li>\n<li><strong>In Use<\/strong> &#8211; A process currently holds a runtime reference to package content, preventing the package from being destaged.<\/li>\n<li><strong><a href=\"https:\/\/learn.microsoft.com\/windows\/apps\/desktop\/modernize\/framework-packages\/use-the-dynamic-dependency-api\">Dynamic Dependency<\/a><\/strong> &#8211; A persisted<sup>1<\/sup> dynamic dependency has been defined, and the package is the only package on the system satisfying the dependency&#8217;s criteria. \n<ul>\n<li>Only Main and Framework packages may satisfy Dynamic dependencies<\/li>\n<\/ul>\n<\/li>\n<li><strong>Explicit User Registration<\/strong> &#8211; The package is explicitly registered to a user. This is tracked internally for each package registration. Main and Optional packages normally create explicit user registrations when registered for a user.<\/li>\n<li><strong>Unified Update Platform (UUP) Product Membership<\/strong> &#8211; The package is included in a <a href=\"https:\/\/blogs.windows.com\/windows-insider\/2016\/11\/03\/introducing-unified-update-platform-uup\/\">UUP<\/a> product.<\/li>\n<li><strong>Pinned<\/strong> &#8211; The package has been pinned on the system.<\/li>\n<\/ol>\n<p>As long as any of these conditions remain true, the package must stay staged.<\/p>\n<h3>Weak References<\/h3>\n<p>A package <strong>can<\/strong> be destaged while only weak references to it exist.<\/p>\n<p>Weak references don&#8217;t independently keep a package staged. When their backing package is removed, they disappear automatically.<\/p>\n<p>The primary form of weak reference is:<\/p>\n<ol>\n<li><strong>Resource Package Relationship<\/strong> &#8211; The existence of another package in the same package family creates a weak reference to the package. \n<ul>\n<li>Only Main and Optional packages support Resource packages<\/li>\n<li>Framework packages don&#8217;t support Resource packages<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>Weak references alone don&#8217;t prevent a package from being destaged.<\/p>\n<h2>Why Doesn&#8217;t Deployment Immediately Destage?<\/h2>\n<p>Why doesn&#8217;t Deployment immediately scan and destage a package every time a reference disappears?<\/p>\n<p>Reference removal and package destaging are intentionally decoupled. Some reference changes occur outside Deployment operations, so Deployment periodically reevaluates package reachability rather than immediately destaging a package whenever a reference changes.<\/p>\n<h2>Putting It Together<\/h2>\n<p>When a <a href=\"https:\/\/devblogs.microsoft.com\/insidemsix\/remove-is-not-uninstall\/\">package is removed<\/a>, Deployment first removes the package&#8217;s registration and user-specific integrations.<\/p>\n<p>Deployment then reevaluates whether any strong references to the package remain.<\/p>\n<p>If at least one strong reference remains, the package stays staged.<\/p>\n<p>If no strong references remain, Deployment may destage the package and reclaim the package payload from disk.<\/p>\n<p>If strong references remain, the package remains reachable and therefore stays staged.<\/p>\n<p>Much like any garbage-collected system, package lifetime is based not on intent, but on reachability.<\/p>\n<hr \/>\n<p><sup>1<\/sup> Dynamic dependencies are defined programmatically at runtime via <a href=\"https:\/\/learn.microsoft.com\/windows\/win32\/api\/appmodel\/nf-appmodel-trycreatepackagedependency\">TryCreatePackageDependency<\/a>. Dynamic dependencies defined with <code>lifetimeKind<\/code>=<code>FilePath<\/code> or <code>RegistryKey<\/code> are persistent vs those defined with <code>lifetimeKind<\/code>=<code>Process<\/code> are transient. Persistent definitions are stored by Deployment until explicitly deleted. Transient definitions are deleted when the process ends, or if explicitly deleted before process death.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>MSIX uses a Garbage Collection (GC) design for staged package lifetime and destaging. Throughout this article: Remove refers to the Deployment operation requested by the caller. Deregister refers to removing a user&#8217;s registration for a package. Destage refers to removing the staged package payload from disk. Package Core Principles A staged package can&#8217;t be destaged [&hellip;]<\/p>\n","protected":false},"author":911,"featured_media":81,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[8,3,21,22,24,23,2,27,14,15,25,26],"class_list":["post-250","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-msix","tag-architecture","tag-deployment","tag-destage","tag-dynamicdependency","tag-framework","tag-hostruntime","tag-msix","tag-pin","tag-provision","tag-remove","tag-resource","tag-uup"],"acf":[],"blog_post_summary":"<p>MSIX uses a Garbage Collection (GC) design for staged package lifetime and destaging. Throughout this article: Remove refers to the Deployment operation requested by the caller. Deregister refers to removing a user&#8217;s registration for a package. Destage refers to removing the staged package payload from disk. Package Core Principles A staged package can&#8217;t be destaged [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts\/250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/users\/911"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/comments?post=250"}],"version-history":[{"count":2,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts\/250\/revisions"}],"predecessor-version":[{"id":264,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts\/250\/revisions\/264"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/media\/81"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/media?parent=250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/categories?post=250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/tags?post=250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}