diff --git a/README.md b/README.md
index 7f9fa66e..d7bd6ae4 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,7 @@ Mongo | The MongoDB database
Mockito | [Mockito](https://site.mockito.org/), the most popular mocking framework for Java unit tests
OCA | Oracle Certified Associate Java SE 8
OCP | Oracle Certified Professional Java SE 8
+Reliability | Tips to make production more reliable.
Rest | RESTful API using [Jersey][jersey].
Typesafe Config | [Typesafe Config](https://github.com/lightbend/config), configuration library for JVM languages.
XML | XML serialization, XPath, XSD.
diff --git a/pom.xml b/pom.xml
index c6375c26..b85dfdb6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,6 +58,7 @@
guava
jetty
protobuf
+ reliability
diff --git a/reliability/pom.xml b/reliability/pom.xml
new file mode 100644
index 00000000..e4b03e78
--- /dev/null
+++ b/reliability/pom.xml
@@ -0,0 +1,32 @@
+
+
+
+ java-examples-parent
+ io.mincong
+ 1.0.0-SNAPSHOT
+
+ 4.0.0
+
+ java-examples-reliability
+ Java Examples - Reliability
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+
diff --git a/reliability/src/main/java/io/mincong/reliability/Throttler.java b/reliability/src/main/java/io/mincong/reliability/Throttler.java
new file mode 100644
index 00000000..80d78493
--- /dev/null
+++ b/reliability/src/main/java/io/mincong/reliability/Throttler.java
@@ -0,0 +1,43 @@
+package io.mincong.reliability;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Throttler {
+
+ private final int messageLimit;
+
+ public Throttler(int messageLimit) {
+ this.messageLimit = messageLimit;
+ }
+
+ public ThrottleResult throttle(List messages) {
+ var passed = new ArrayList();
+ var throttled = new ArrayList();
+ var quota = messageLimit;
+
+ for (var message : messages) {
+ if (quota > 0) {
+ passed.add(message);
+ quota--;
+ } else {
+ throttled.add(message);
+ }
+ }
+ /*
+ * You can also add metrics or logs on the output to improve the
+ * observability of the system.
+ */
+ return new ThrottleResult(passed, throttled);
+ }
+
+ public static class ThrottleResult {
+ public final List passed;
+ public final List throttled;
+
+ public ThrottleResult(List passed, List throttled) {
+ this.passed = passed;
+ this.throttled = throttled;
+ }
+ }
+}
diff --git a/reliability/src/test/java/io/mincong/reliability/ThrottlerTest.java b/reliability/src/test/java/io/mincong/reliability/ThrottlerTest.java
new file mode 100644
index 00000000..da7a586d
--- /dev/null
+++ b/reliability/src/test/java/io/mincong/reliability/ThrottlerTest.java
@@ -0,0 +1,29 @@
+package io.mincong.reliability;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+class ThrottlerTest {
+
+ @Test
+ void throttle_lessMessagesThanLimit() {
+ var throttler = new Throttler(3);
+
+ var result = throttler.throttle(List.of("1", "2"));
+
+ assertThat(result.passed).containsExactly("1", "2");
+ assertThat(result.throttled).isEmpty();
+ }
+
+ @Test
+ void throttle_moreMessagesThanLimit() {
+ var throttler = new Throttler(3);
+
+ var result = throttler.throttle(List.of("1", "2", "3", "4"));
+
+ assertThat(result.passed).containsExactly("1", "2", "3");
+ assertThat(result.throttled).containsExactly("4");
+ }
+}