 
 private extension CocoaMQTT {
     
+    // MARK: -- RetryQueue
+    
+    class RetryQueue {
+        let depth: UInt
+        let duration: TimeInterval
+        
+        private var _queue = [Date]()
+     
+        init(depth: UInt, duration: TimeInterval) {
+            self.depth = depth
+            self.duration = duration
+            
+            printNotice("RetryQueue init. Depth: \(depth), duration: \(duration)")
+        }
+        
+        func append(timestamp: Date) throws {
+            printDebug("RetryQueue append timestamp: \(timestamp), now queue count: \(_queue.count), queue: \(_queue)")
+            
+            // remove expired record
+            _queue = _queue.filter { $0.addingTimeInterval(duration) >= timestamp }
+            
+            guard UInt(_queue.count) < depth else {
+                throw NSError(domain: "CocoaMQTT-RetryFusing", code: -1, userInfo: ["depth": depth, "duration": duration, "count": _queue.count])
+            }
+            
+            _queue.append(timestamp)
+        }
+        
+        func reset() {
+            printNotice("RetryQueue reset.")
+            
+            _queue = []
+        }
+    }
+    
     // MARK: -- Retry
     
     class Retry {
         let retry: Bool
         let maxRetryCount: UInt
         let step: TimeInterval
+        let fusing: RetryQueue
         
         var retriedCount: UInt = 0
         private var timer: Timer? = nil

        self.clientID = clientID
        self.host = host
        self.port = port
        retry = Retry(retry: retrySetting.retry, maxRetryCount: retrySetting.maxCount, step: retrySetting.step)
        super.init()
        buffer.delegate = self
        printNotice("init")

        
        // MARK: --- life cycle
        
        init(retry needRetry: Bool, maxRetryCount maxCount: UInt, step s: TimeInterval, fusingDepth: UInt, fusingDuration: TimeInterval) {
            retry = needRetry
            maxRetryCount = maxCount
            step = s
            retrying = false
            
            fusing = RetryQueue(depth: fusingDepth, duration: fusingDuration)
            printNotice("Object.Retry init. retry:\(retry), maxRetryCount:\(maxRetryCount), step:\(step), retrying:\(retrying), fusingDepth: \(fusingDepth), fusingDuration: \(fusingDuration)")
        }
        
        deinit {
