diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 3d06161..0279f6e 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -4,9 +4,9 @@ ADD_DEFINITIONS(-I..)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/..)
 
 IF (BUILD_EXAMPLES)
-	ADD_EXECUTABLE(server server.c)
+	ADD_EXECUTABLE(server server.c count.c)
 	TARGET_LINK_LIBRARIES(server ubus ubox blobmsg_json)
 
-	ADD_EXECUTABLE(client client.c)
+	ADD_EXECUTABLE(client client.c count.c)
 	TARGET_LINK_LIBRARIES(client ubus ubox)
 ENDIF()
diff --git a/examples/client.c b/examples/client.c
index 4d6b6ec..b586eaf 100644
--- a/examples/client.c
+++ b/examples/client.c
@@ -17,6 +17,7 @@
 #include <libubox/ustream.h>
 
 #include "libubus.h"
+#include "count.h"
 
 static struct ubus_context *ctx;
 static struct blob_buf b;
@@ -55,10 +56,85 @@ static void test_client_notify_cb(struct uloop_timeout *timeout)
 	uloop_timeout_set(timeout, 1000);
 }
 
+enum {
+	RETURN_CODE,
+	__RETURN_MAX,
+};
+
+static const struct blobmsg_policy return_policy[__RETURN_MAX] = {
+	[RETURN_CODE] = { .name = "rc", .type = BLOBMSG_TYPE_INT32 },
+};
+
+static void test_count_data_cb(struct ubus_request *req,
+				    int type, struct blob_attr *msg)
+{
+	struct blob_attr *tb[__RETURN_MAX];
+	int rc;
+	uint32_t count_to = *(uint32_t *)req->priv;
+
+	blobmsg_parse(return_policy, __RETURN_MAX, tb, blob_data(msg), blob_len(msg));
+
+	if (!tb[RETURN_CODE]) {
+		fprintf(stderr, "No return code received from server\n");
+		return;
+	}
+	rc = blobmsg_get_u32(tb[RETURN_CODE]);
+	if (rc)
+		fprintf(stderr, "Corruption of data with count up to '%u'\n", count_to);
+	else
+		fprintf(stderr, "Server validated our count up to '%u'\n", count_to);
+}
+
+static void test_count(struct uloop_timeout *timeout)
+{
+	enum {
+		COUNT_TO_MIN = 10000,
+		COUNT_TO_MAX = 1000000,
+		PROGRESSION  = 100,
+	};
+
+	uint32_t id;
+	static uint32_t count_to = 100000;
+	static int count_progression = PROGRESSION;
+	char *s;
+
+	if (count_to <= COUNT_TO_MIN)
+		count_progression = PROGRESSION;
+	else if (count_to >= COUNT_TO_MAX)
+		count_progression = -PROGRESSION;
+
+	count_to += count_progression;
+
+	s = count_to_number(count_to);
+	if (!s)
+		fprintf(stderr, "Could not allocate memory to count up to '%u'\n", count_to);
+
+	fprintf(stderr, "Sending count up to '%u'; string has length '%u'\n",
+	        count_to, (uint32_t)strlen(s));
+	blob_buf_init(&b, 0);
+	blobmsg_add_u32(&b, "to", count_to);
+	blobmsg_add_string(&b, "string", s);
+
+	if (ubus_lookup_id(ctx, "test", &id)) {
+		fprintf(stderr, "Failed to look up test object\n");
+		return;
+	}
+
+	ubus_invoke(ctx, id, "count", b.head, test_count_data_cb, &count_to, 5000);
+
+	free(s);
+
+	uloop_timeout_set(timeout, 2000);
+}
+
 static struct uloop_timeout notify_timer = {
 	.cb = test_client_notify_cb,
 };
 
+static struct uloop_timeout count_timer = {
+	.cb = test_count,
+};
+
 static void test_client_fd_data_cb(struct ustream *s, int bytes)
 {
 	char *data, *sep;
@@ -121,6 +197,8 @@ static void client_main(void)
 	req.complete_cb = test_client_complete_cb;
 	ubus_complete_request_async(ctx, &req);
 
+	uloop_timeout_set(&count_timer, 2000);
+
 	uloop_run();
 }
 
diff --git a/examples/count.c b/examples/count.c
new file mode 100644
index 0000000..e3e9c8a
--- /dev/null
+++ b/examples/count.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "count.h"
+
+char *count_to_number(uint32_t num)
+{
+	uint32_t ptr = 0, size = 0;
+	uint32_t written = 0, i;
+	int new_line_every_n_numbers = 30;
+	char *s;
+
+	for (i=0; i < num; ++i) {
+		size += snprintf(NULL, 0, "%u ", i);
+		if (i > 0 && i % new_line_every_n_numbers == 0)
+			size++;
+	}
+	size++; /* one for null char */
+
+	s = calloc(size, sizeof(char));
+	if (!s)
+		goto out;
+
+	for (i=0; i < num; ++i) {
+		written = sprintf(&s[ptr], "%u ", i);
+		ptr  += written;
+		if (i > 0 && i % new_line_every_n_numbers == 0) {
+			sprintf(&s[ptr], "\n");
+			ptr++;
+		}
+	}
+
+out:
+	return s;
+}
diff --git a/examples/count.h b/examples/count.h
new file mode 100644
index 0000000..1f90f21
--- /dev/null
+++ b/examples/count.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __COUNT_H
+#define __COUNT_H
+
+char *count_to_number(uint32_t num);
+
+#endif
diff --git a/examples/server.c b/examples/server.c
index 95eba5e..bbb3347 100644
--- a/examples/server.c
+++ b/examples/server.c
@@ -16,6 +16,7 @@
 
 #include <libubox/blobmsg_json.h>
 #include "libubus.h"
+#include "count.h"
 
 static struct ubus_context *ctx;
 static struct ubus_subscriber test_event;
@@ -149,9 +150,48 @@ static int test_watch(struct ubus_context *ctx, struct ubus_object *obj,
 	return ret;
 }
 
+enum {
+    COUNT_TO,
+    COUNT_STRING,
+    __COUNT_MAX
+};
+
+static const struct blobmsg_policy count_policy[__COUNT_MAX] = {
+    [COUNT_TO] = { .name = "to", .type = BLOBMSG_TYPE_INT32 },
+    [COUNT_STRING] = { .name = "string", .type = BLOBMSG_TYPE_STRING },
+};
+
+static int test_count(struct ubus_context *ctx, struct ubus_object *obj,
+		      struct ubus_request_data *req, const char *method,
+		      struct blob_attr *msg)
+{
+	struct blob_attr *tb[__COUNT_MAX];
+	char *s1, *s2;
+	uint32_t num;
+
+	blobmsg_parse(count_policy, __COUNT_MAX, tb, blob_data(msg), blob_len(msg));
+	if (!tb[COUNT_TO] || !tb[COUNT_STRING])
+		return UBUS_STATUS_INVALID_ARGUMENT;
+
+	num = blobmsg_get_u32(tb[COUNT_TO]);
+	s1 = blobmsg_get_string(tb[COUNT_STRING]);
+	s2 = count_to_number(num);
+	if (!s1 || !s2) {
+		free(s2);
+		return UBUS_STATUS_UNKNOWN_ERROR;
+	}
+	blob_buf_init(&b, 0);
+	blobmsg_add_u32(&b, "rc", strcmp(s1, s2));
+	ubus_send_reply(ctx, req, b.head);
+	free(s2);
+
+	return 0;
+}
+
 static const struct ubus_method test_methods[] = {
 	UBUS_METHOD("hello", test_hello, hello_policy),
 	UBUS_METHOD("watch", test_watch, watch_policy),
+	UBUS_METHOD("count", test_count, count_policy),
 };
 
 static struct ubus_object_type test_object_type =