Slow first Realm Init on Cold Launch

I have this setup for initializing realm in my app (there are a bunch of time stamps because I’m going crazy trying to debug why it’s so slow).
I now notice that the only hang in this bit of code is when actually initializing Realm.
Between print("Calling realm init at: \(Date())") and print("Realm finished initializing at: \(Date())") it can take up to 30 seconds.

One thing to note is that this issue only affects cold launches. Warm launches work great. Is there anything i am doing wrong in my realm initialization?

public extension DispatchQueue {

    static let realmThread = DispatchQueue(
        label: "realmThread",
        qos: .background)
    
}
let config = user.configuration(partitionValue: "\(user.id)")
DispatchQueue.realmThread.async {
    do {
        try autoreleasepool {
            print("Calling realm init at: \(Date())") // Up to 30 seconds between here
            let realm = try Realm(configuration: config, queue: DispatchQueue.realmThread)
            print("Realm finished initializing at: \(Date())") // and here
            self.realm = realm
            print("Realm set into local property at: \(Date())")
            completionHandler(true, nil)
            print("Completion handler fired at: \(Date())")
        }

    } catch(let error) {
        print(error)
        print()
    }
}
1 Like

Background QoS is almost certainly not what you want. It’s intended for long-running low importance tasks than can be safely suspended indefinitely. In practice background QoS queues are not executed at all in low-power mode and typically only run on efficiency cores when they are executed, and the OS has a lot of low-importance background QoS work that you’re effectively yielding to.

Energy Efficiency Guide for iOS Apps: Prioritize Work with Quality of Service Classes has a decent description of what the QoS levels mean, but the short summary is that anything which will hard block the main thread until it’s done should be User-interactive, short background tasks should be User-initiated, and Utility is for background tasks where showing a progress bar is appropriate. Background is for long-running tasks where showing a progress bar doesn’t make sense because the user doesn’t care when it completes or that it’s running.

3 Likes

Thank you, this absolutely makes a ton of sense and completely solved my problem. Much obliged!

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.