diff --git a/README.md b/README.md
index 0eef38e..54ca7ed 100644
--- a/README.md
+++ b/README.md
@@ -97,7 +97,10 @@ prompts that are hidden, using `hide_input=True`, are sent to the user DM, and c
 
 Note that, echo and prompt will send a message in the same channel as the message that triggered the command invocation.
 
-Calls to echo are buffered, the buffer is flushed either when there is a prompt or when the command finishes execution.
+Calls to echo are buffered. When the buffer is flushed, its content is sent in 2K chunks (limit set by discord.)
+The buffer can be flushed automatically when there is a prompt, or the command finishes execution, or the content
+in the buffer exceeds the 2K limit.
+
 It's also possible to flush the buffer by passing `flush=True` to `click.echo` call.
 
 ## Acknowledgements
diff --git a/smalld_click/conversation.py b/smalld_click/conversation.py
index fcacfb1..a094244 100644
--- a/smalld_click/conversation.py
+++ b/smalld_click/conversation.py
@@ -6,6 +6,9 @@ click_prompt = click.prompt
 click_echo = click.echo
 
 
+MESSAGE_CHARACTERS_LIMIT = 2000
+
+
 class Conversation:
     def __init__(self, runner, message, timeout):
         self.runner = runner
@@ -44,11 +47,11 @@ class Conversation:
     def flush(self):
         content = self.echo_buffer.getvalue()
         self.echo_buffer = io.StringIO()
-        if not content.strip():
-            return
 
         smalld, channel_id = self.runner.smalld, self.channel_id
-        smalld.post(f"/channels/{channel_id}/messages", {"content": content})
+        for message in chunked(content, MESSAGE_CHARACTERS_LIMIT):
+            if message.strip():
+                smalld.post(f"/channels/{channel_id}/messages", {"content": message})
 
     def wait_for_message(self):
         handle = self.runner.add_listener(self.user_id, self.channel_id)
@@ -72,3 +75,8 @@ class Conversation:
 
 def get_conversation():
     return click.get_current_context().find_object(Conversation)
+
+
+def chunked(it, n):
+    for i in range(0, len(it), n):
+        yield it[i : i + n]

diff --git a/test/test_smalld_click.py b/test/test_smalld_click.py
index ac4461f..bdecef9 100644
--- a/test/test_smalld_click.py
+++ b/test/test_smalld_click.py
@@ -251,3 +251,21 @@ def test_patches_click_functions_in_context_only(smalld):
 
     assert click.echo is click_echo
     assert click.prompt is click_prompt
+
+
+def test_sends_chunked_messages_not_exceeding_message_length_limit(subject, smalld):
+    @click.command()
+    def command():
+        click.echo("a" * 3000)
+
+    subject.cli = command
+
+    subject.on_message(make_message("command"))
+
+    assert smalld.post.call_count == 2
+    smalld.post.assert_has_calls(
+        [
+            call(POST_MESSAGE_ROUTE, {"content": "a" * 2000}),
+            call(POST_MESSAGE_ROUTE, {"content": "a" * 1000 + "\n"}),
+        ]
+    )

Send messages in 2K characters chunks to avoid hitting message length limit
There is a limit of 2K characters for messages sent through discord.
test/test_smalld_click.py::test_sends_chunked_messages_not_exceeding_message_length_limit
test/test_smalld_click.py::test_exposes_correct_context test/test_smalld_click.py::test_parses_command test/test_smalld_click.py::test_handles_echo test/test_smalld_click.py::test_buffers_calls_to_echo test/test_smalld_click.py::test_should_not_send_empty_messages test/test_smalld_click.py::test_handles_prompt test/test_smalld_click.py::test_sends_prompts_without_buffering test/test_smalld_click.py::test_drops_conversation_when_timed_out test/test_smalld_click.py::test_prompts_in_DM_for_hidden_prompts test/test_smalld_click.py::test_only_responds_to_hidden_prompts_answers_in_DM test/test_smalld_click.py::test_continues_conversation_in_DM_after_hidden_prompt test/test_smalld_click.py::test_patches_click_functions_in_context_only