static int  cfg_runtime_ms     = 4200;
 static int  cfg_verbose;
 static int  cfg_waittime_ms    = 500;
+static int  cfg_notification_limit = 32;
 static bool cfg_zerocopy;
 
 static socklen_t cfg_alen;
 static long packets, bytes, completions, expected_completions;
 static int  zerocopied = -1;
 static uint32_t next_completion;
+static uint32_t sends_since_notify;
 
 static unsigned long gettimeofday_ms(void)
 {
                error(1, errno, "send");
        if (cfg_verbose && ret != len)
                fprintf(stderr, "send: ret=%u != %u\n", ret, len);
+       sends_since_notify++;
 
        if (len) {
                packets++;
 static void do_recv_completions(int fd, int domain)
 {
        while (do_recv_completion(fd, domain)) {}
+       sends_since_notify = 0;
 }
 
 /* Wait for all remaining completions on the errqueue */
                else
                        do_sendmsg(fd, &msg, cfg_zerocopy, domain);
 
+               if (cfg_zerocopy && sends_since_notify >= cfg_notification_limit)
+                       do_recv_completions(fd, domain);
+
                while (!do_poll(fd, POLLOUT)) {
                        if (cfg_zerocopy)
                                do_recv_completions(fd, domain);
 
        cfg_payload_len = max_payload_len;
 
-       while ((c = getopt(argc, argv, "46c:C:D:i:mp:rs:S:t:vz")) != -1) {
+       while ((c = getopt(argc, argv, "46c:C:D:i:l:mp:rs:S:t:vz")) != -1) {
                switch (c) {
                case '4':
                        if (cfg_family != PF_UNSPEC)
                        if (cfg_ifindex == 0)
                                error(1, errno, "invalid iface: %s", optarg);
                        break;
+               case 'l':
+                       cfg_notification_limit = strtoul(optarg, NULL, 0);
+                       break;
                case 'm':
                        cfg_cork_mixed = true;
                        break;