diff --git a/benchmark/src/event.rs b/benchmark/src/event.rs
new file mode 100644
index 00000000..e273a9a7
--- /dev/null
+++ b/benchmark/src/event.rs
@@ -0,0 +1,50 @@
+/// Inspired by https://github.com/orhun/rust-tui-template
+use crossterm::event;
+use tokio::sync::{mpsc, broadcast};
+use std::time::{Duration, Instant};
+
+/// Events
+#[derive(Debug)]
+pub(crate) enum Event {
+    /// Terminal tick.
+    Tick,
+    /// Key press.
+    Key(event::KeyEvent),
+    /// Terminal resize.
+    Resize(u16, u16),
+}
+
+pub(crate) async fn terminal_event_task(fps: u32, event_sender: mpsc::Sender<Event>,
+                                        mut shutdown_receiver: broadcast::Receiver<()>,
+                                        _shutdown_guard_sender: mpsc::Sender<()>,
+) {
+    tokio::select! {
+        _ = event_loop(fps, event_sender)  => {
+        },
+        _ = shutdown_receiver.recv() => {}
+    }
+}
+
+async fn event_loop(fps: u32, event_sender: mpsc::Sender<Event>,
+) {
+    let per_frame = Duration::from_secs(1) / fps as u32;
+    let mut last_frame = Instant::now();
+    loop {
+        if let Some(sleep) = per_frame.checked_sub(last_frame.elapsed()) {
+            tokio::time::sleep(sleep).await;
+        }
+
+        if event::poll(Duration::from_secs(0)).expect("no events available") {
+            match event::read().expect("unable to read event") {
+                event::Event::Key(e) => event_sender.send(Event::Key(e)).await.unwrap_or(()),
+                event::Event::Resize(w, h) => event_sender.send(Event::Resize(w, h)).await.unwrap_or(()),
+                _ => (),
+            }
+        }
+
+        if last_frame.elapsed() >= per_frame {
+            event_sender.send(Event::Tick).await.unwrap_or(());
+            last_frame = Instant::now();
+        }
+    }
+}
diff --git a/benchmark/src/generation.rs b/benchmark/src/generation.rs
index bdc7d084..024b1320 100644
--- a/benchmark/src/generation.rs
+++ b/benchmark/src/generation.rs
@@ -55,7 +55,6 @@ pub(crate) async fn generation_task(
         },
         _ = shutdown_receiver.recv() => {}
     }
-    ;
 }
 
 async fn generate_runs(tokenizer: Tokenizer,
diff --git a/benchmark/src/lib.rs b/benchmark/src/lib.rs
index 935c11dc..61acc331 100644
--- a/benchmark/src/lib.rs
+++ b/benchmark/src/lib.rs
@@ -3,6 +3,7 @@ extern crate core;
 mod ui;
 mod utils;
 mod generation;
+mod event;
 
 use crate::ui::UI;
 use tokenizers::Tokenizer;