August 11th, 2026
0 reactions

Remove and Package Lifetime

Principal Software Engineer

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’s registration for a package.
  • Destage refers to removing the staged package payload from disk.

Package Core Principles

A staged package can’t be destaged while any references to it exist. This is a direct consequence of MSIX’s core architectural principles:

  • staged packages are immutable
  • staged packages are shared across users
  • staged packages may satisfy dependencies for other packages

Consequently, removing a package’s payload from disk is not a direct result of a single API call.

Instead, package payloads are automatically destaged when they are no longer needed.

Even then, destaging may not occur immediately.

Some actions that remove a reference don’t directly trigger Deployment activity. In these cases, the staged package will be destaged the next time Deployment evaluates it.

In practice, destaging usually occurs soon after the final strong reference is removed.

Package References

Packages remain staged because something references them. Some package types have additional referencing behaviors or caveats, but broadly speaking:

References may be either strong or weak.

Almost all types of references are strong references, and are commonly referred to simply as references.

Strong References

A package can’t be destaged while a strong reference to it exists.

Forms of strong reference include:

  1. <PackageDependency> – 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.
    • Only Framework packages can satisfy a \.
  2. <HostRuntimeDependency> – A package providing a Host Runtime may satisfy a \. Only Main and Framework packages can participate in Host Runtime relationships.
  3. Provisioned – A package is provisioned for users on the system.
  4. In Use – A process currently holds a runtime reference to package content, preventing the package from being destaged.
  5. Dynamic Dependency – A persisted1 dynamic dependency has been defined, and the package is the only package on the system satisfying the dependency’s criteria.
    • Only Main and Framework packages may satisfy Dynamic dependencies
  6. Explicit User Registration – 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.
  7. Unified Update Platform (UUP) Product Membership – The package is included in a UUP product.
  8. Pinned – The package has been pinned on the system.

As long as any of these conditions remain true, the package must stay staged.

Weak References

A package can be destaged while only weak references to it exist.

Weak references don’t independently keep a package staged. When their backing package is removed, they disappear automatically.

The primary form of weak reference is:

  1. Resource Package Relationship – The existence of another package in the same package family creates a weak reference to the package.
    • Only Main and Optional packages support Resource packages
    • Framework packages don’t support Resource packages

Weak references alone don’t prevent a package from being destaged.

Why Doesn’t Deployment Immediately Destage?

Why doesn’t Deployment immediately scan and destage a package every time a reference disappears?

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.

Putting It Together

When a package is removed, Deployment first removes the package’s registration and user-specific integrations.

Deployment then reevaluates whether any strong references to the package remain.

If at least one strong reference remains, the package stays staged.

If no strong references remain, Deployment may destage the package and reclaim the package payload from disk.

If strong references remain, the package remains reachable and therefore stays staged.

Much like any garbage-collected system, package lifetime is based not on intent, but on reachability.


1 Dynamic dependencies are defined programmatically at runtime via TryCreatePackageDependency. Dynamic dependencies defined with lifetimeKind=FilePath or RegistryKey are persistent vs those defined with lifetimeKind=Process 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.

Author

Howard Kapustein
Principal Software Engineer

MSIX Development Engineer/Architect

0 comments