Ask and tell are the two fundamental patterns for communication between actors in Akka and Pekko ( the open-source version of Akka). While both are intended to send messages to actors, they differ significantly in performance, usage scenarios, and syntax. Developers, especially beginners, often get confused about choosing one over the other. I hope this short post will help clear this confusion.
Tell pattern ( ! ) – Fire and Forget ✅
The tell is the most commonly used messaging pattern in Akka. It is an asynchronous, single-way communication pattern. When an actor sends a message using the tell pattern, it doesn’t have a built-in way to receive a reply. Once the message is sent, the sender’s job is over. It is nonblocking and asynchronous.
Example of Tell Using Java & Scala
//Scala Code - tell pattern
actorRef ! Message
case class Greet(name: String)
val greeter = system.actorOf(Props[Greeter], "greeter")
greeter ! Greet("hello world !")
/** Java */
ActorSystem system = ActorSystem.create("test");
ActorRef actor1 = system.actorOf(Props.create(Actor1.class), "actor-1");
// Send messages to the actor using tell
actor1.tell(new Message("Hello World!"), ActorRef.noSender());
Code language: Java (java)
Advantages
- Non Blocking
- High performance
- Fire and Forget
Disadvantages
No direct way to receive a reply as part of the return message of tell+Additi
Additional complexity is involved in determining whether the message was successfully processed by the receiver. If the receiver sends the reply, it comes as a message to the sender’s inbox. The sender has to use some identifier to determine this reply is for a particular message. This can be accomplished if the sender includes a message ID in the message and the receiver, when sending a message to the sender, uses the same message ID.
Use tell when
- The sender actor doesn’t need a response – if the sender’s job is only to notify or trigger the receiver actor
- You are implementing a system for High throughput and performance
Ask Pattern ( ? ) – Request Response mechanism
The ask pattern (?) allows an actor to send a message to another actor when the sender expects a response back. Ask returns a Future that completes when the response arrives.
//Scala code snipper
import akka.pattern.ask
import akka.util.Timeout
implicit val timeout = Timeout(1.seconds)
val future = actorRef ? Message
Code language: JavaScript (javascript)
Ask – Java Example
import akka.actor.*;
import akka.pattern.Patterns;
import akka.util.Timeout;
import scala.concurrent.Future;
import java.time.Duration;
import java.util.concurrent.CompletionStage;
public class AskPatternExample {
// Define a message
public static class HelloMsg {
public final String content;
public HelloMsg(String content) {
this.content = content;
}
}
// Define a responder actor
public static class ReceiverActor extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder()
.match(AskMessage.class, msg -> {
getSender().tell("Received: " + msg.content, getSelf());
})
.build();
}
}
public static void main(String[] args) {
ActorSystem system = ActorSystem.create("ask-pattern-demo");
ActorRef responder = system.actorOf(Props.create(ReceiverActor.class), "responder");
// Timeout for the ask
Timeout timeout = Timeout.create(Duration.ofSeconds(3));
// Ask pattern: send message and expect a future response
Future<Object> future = Patterns.ask(responder, new HelloMsg("Hello, World!"), timeout);
// Convert to CompletionStage (Java-friendly)
CompletionStage<Object> completionStage = FutureConverters.toJava(future);
// Handle the response asynchronously
completionStage.thenAccept(response -> {
System.out.println("Got reply: " + response);
system.terminate(); // Shutdown actor system after response
});
}
}
Code language: JavaScript (javascript)
Key Differences
Feature | tell | ask |
---|---|---|
Type | Fire and Forget | Request – Response |
Return Type | No Return ( defaults to Unit ) | Future[Any] |
Mode | Non-Blocking ( Expects Response) | No Return, defaults to Unit |
Overhead | negligible | High Compared to tell |
Performance | Superior to Ask | Low compared to Ask |
Overall, tell is a better option, even though both are non-blocking. The difference becomes relevant only under heavy loads. For most of the use cases, use tell. Prefer ask when you are integrating with legacy system, and you must know whether there is a response or failure. When using ask ( ? ), remember to define a timeout for ask. This is one of the best practices
Leave a Reply