Docs Menu

Compact a Realm - Swift SDK

On this page

  • Overview
  • Compact a Realm
  • Make a Compacted Copy
  • How Compacting Works
  • When to Compact a Realm
  • Compact a Realm Asynchronously
  • Summary

The size of a Realm Database file is always larger than the total size of the objects stored within it. This architecture enables some of realm's great performance, concurrency, and safety benefits.

Tip
See also:

Realm writes new data within unused space tracked inside file. In some situations, unused space may comprise a significant portion of a realm file. If file size grows large enough to negatively impact performance, compact the realm.

Tip
Implement Compacting in Your Production Application

Every production application should implement a shouldCompactOnLaunch callback to periodically reduce the realm file size. For more information about how often to compact a realm, see: When to Compact a Realm.

Use shouldCompactOnLaunch() (Swift) or shouldCompactOnLaunch (Objective-C) on a realm's configuration object to compact a realm. Specify conditions to execute this method, such as:

  • The size of the file on disk
  • How much free space the file contains
Important
Compacting may not occur

Compacting cannot occur while a realm is being accessed, regardless of any configuration settings.

You can save a compacted (and optionally encrypted) copy of a realm to another file location with the Realm.writeCopy(toFile:encryptionKey:) method. The destination file cannot already exist.

Important

Avoid calling this method within a write transaction. If called within a write transaction, this method copies the absolute latest data. This includes any uncommitted changes you made in the transaction before this method call.

Realm compacting works by:

  1. Reading the entire contents of the realm file
  2. Writing the contents to a new file at a different location
  3. Replacing the original file

If the file contains a lot of data, this can be an expensive operation.

Compacting a realm can be an expensive operation that can block the UI thread. Your application should not compact every time you open a realm. Instead, try to optimize compacting so your application does it just often enough to prevent the file size from growing too large. If your application runs in a resource-constrained environment, you may want to compact when you reach a certain file size or when the file size negatively impacts performance.

These recommendations can help you start optimizing compaction for your application:

  • Set the max file size to a multiple of your average realm state size. If your average realm state size is 10MB, you might set the max file size to 20MB or 40MB, depending on expected usage and device constraints.
  • As a starting point, compact realms when more than 50% of the realm file size is no longer in use. Divide the currently used bytes by the total file size to determine the percentage of space that is currently used. Then, check for that to be less than 50%. This means that greater than 50% of your realm file size is unused space, and it is a good time to compact. After experimentation, you may find a different percentage works best for your application.

These calculations might look like this in your shouldCompactOnLaunch callback:

// Set a maxFileSize equal to 20MB in bytes
let maxFileSize = 20 * 1024 * 1024
// Check for the realm file size to be greater than the max file size,
// and the amount of bytes currently used to be less than 50% of the
// total realm file size
return (realmFileSizeInBytes > maxFileSize) && (Double(usedBytes) / Double(realmFileSizeInBytes)) < 0.5

Experiment with conditions to find the right balance of how often to compact realm files in your application.

When you use the Swift async/await syntax to open a realm asynchronously, you can compact a realm in the background.

func testAsyncCompact() async {
let config = Realm.Configuration(shouldCompactOnLaunch: { totalBytes, usedBytes in
// totalBytes refers to the size of the file on disk in bytes (data + free space)
// usedBytes refers to the number of bytes used by data in the file
// Compact if the file is over 100MB in size and less than 50% 'used'
let oneHundredMB = 100 * 1024 * 1024
return (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.5
})
do {
// Realm is compacted asynchronously on the first open if the
// configuration block conditions were met.
let realm = try await Realm(configuration: config)
} catch {
// handle error compacting or opening Realm
}
}

Starting with Realm Swift SDK Versions 10.15.0 and 10.16.0, many of the Realm APIs support the Swift async/await syntax. Projects must meet these requirements:

Swift SDK Version
Swift Version Requirement
Supported OS
10.25.0
Swift 5.6
iOS 13.x
10.15.0 or 10.16.0
Swift 5.5
iOS 15.x
  • Realm Database's architecture enables threading-related benefits, but can result in file size growth.
  • Use compacting to manage file size growth.
  • Define conditions for shouldCompactOnLaunch() to compact a realm.
  • Compacting cannot occur if another process is accessing the realm.
  • You can compact a realm in the background when you use async/await syntax.
←  Encrypt a Realm - Swift SDKClient Resets - Swift SDK →
Give Feedback
© 2022 MongoDB, Inc.

About

  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2022 MongoDB, Inc.