diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSender.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSender.java
index 610b3808b14f417a0ab09edb8f0efc7c4003a2a2..9459e8535c13c063e3ea3c661a3962b77ee08c1f 100644
--- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSender.java
+++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSender.java
@@ -101,6 +101,10 @@ class FileSender {
 		requestObserver.onNext(chunk);
 	}
 
+	public boolean isDone() {
+		return done.get();
+	}
+
 	@RequiredArgsConstructor
 	class StreamReader {
 
diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSender.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSender.java
index 29457e1e4f1af0826f45f899cf8aedfdb289aa81..d0bb1f626fe6d6bf2f9915940c46df9e890bf6c5 100644
--- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSender.java
+++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSender.java
@@ -27,6 +27,7 @@ import static java.util.Objects.*;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.BiFunction;
@@ -62,7 +63,8 @@ public class MessageWithFilesSender {
 	private final BiFunction<byte[], Integer, GrpcSendBayernIdMessageRequest> chunkBuilder;
 
 	private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver;
-	private List<FileSender> fileSenders;
+	private int currentAttachmentIndex = 0;
+	private FileSender currentFileSender;
 
 	public MessageWithFilesSender send() {
 		var responseStreamObserver = BinaryFileUploadStreamObserver.create(resultFuture, this::sendNext);
@@ -99,18 +101,40 @@ public class MessageWithFilesSender {
 	}
 
 	void sendAttachments() {
-		if (isNull(fileSenders)) {
-			fileSenders = createFileSenders();
+		if (attachmentIds.isEmpty()) {
+			completeRequest();
+		} else {
+			sendData();
 		}
-		fileSenders.forEach(FileSender::send);
-		completeRequest();
 	}
 
-	List<FileSender> createFileSenders() {
-		return attachmentIds.stream().map(toAttachment).map(this::buildFileSender).toList();
+	void sendData() {
+		Optional<FileSender> fileSender;
+		while ((fileSender = getFileSender()).isPresent() && requestObserver.isReady()) {
+			fileSender.get().send();
+		}
+		if (fileSender.isEmpty()) {
+			completeRequest();
+		}
+	}
+
+	Optional<FileSender> getFileSender() {
+		if (isNull(currentFileSender)) {
+			currentFileSender = buildNextFileSender();
+			return Optional.of(currentFileSender);
+		}
+		if (!currentFileSender.isDone()) {
+			return Optional.of(currentFileSender);
+		}
+		if (currentAttachmentIndex < attachmentIds.size()) {
+			currentFileSender = buildNextFileSender();
+			return Optional.of(currentFileSender);
+		}
+		return Optional.empty();
 	}
 
-	FileSender buildFileSender(BayernIdAttachment attachment) {
+	FileSender buildNextFileSender() {
+		var attachment = toAttachment.apply(attachmentIds.get(currentAttachmentIndex++));
 		return new FileSender(chunkBuilder, requestObserver, attachmentMetadataMapper.apply(attachment), attachment.getContent());
 	}
 
diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSenderTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSenderTest.java
index 1efd3e30ec8f02a80a7601b6920e6ce40ab2dcd8..ef35049daa926c5dd751258b91897f796469061e 100644
--- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSenderTest.java
+++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSenderTest.java
@@ -28,11 +28,13 @@ import static org.mockito.Mockito.*;
 
 import java.io.InputStream;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.BiFunction;
 import java.util.function.Function;
 
 import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mock;
@@ -178,149 +180,239 @@ class MessageWithFilesSenderTest {
 	@Nested
 	class TestSendAttachments {
 
-		private String attachmentId = "id1";
+		@Test
+		void shouldCallCompleteRequest() {
+			doNothing().when(messageWithFilesSender).completeRequest();
+
+			messageWithFilesSender.sendAttachments();
+
+			verify(messageWithFilesSender).completeRequest();
+		}
+
+		@Test
+		void shouldCallSendData() {
+			ReflectionTestUtils.setField(messageWithFilesSender, "attachmentIds", List.of("attachmentId"));
+			doNothing().when(messageWithFilesSender).sendData();
+
+			messageWithFilesSender.sendAttachments();
+
+			verify(messageWithFilesSender).sendData();
+		}
+
+	}
+
+	@Nested
+	class TestSendData {
 
 		@Mock
 		private FileSender fileSender;
+		@Mock
+		private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver;
 
 		@BeforeEach
 		void setup() {
-			ReflectionTestUtils.setField(messageWithFilesSender, "attachmentIds", List.of(attachmentId));
-			doNothing().when(messageWithFilesSender).completeRequest();
+			ReflectionTestUtils.setField(messageWithFilesSender, "requestObserver", requestObserver);
 		}
 
 		@Test
-		void shouldCallCreateFileSenders() {
-			doReturn(fileSender).when(messageWithFilesSender).buildFileSender(any());
+		void shouldCallGetFileSender() {
+			doReturn(Optional.of(fileSender)).when(messageWithFilesSender).getFileSender();
 
-			messageWithFilesSender.sendAttachments();
+			messageWithFilesSender.sendData();
 
-			verify(messageWithFilesSender).createFileSenders();
+			verify(messageWithFilesSender).getFileSender();
 		}
 
 		@Test
-		void shouldNotRecreateFileSenders() {
-			ReflectionTestUtils.setField(messageWithFilesSender, "fileSenders", List.of(fileSender));
+		void shouldCallSendOnFileSender() {
+			doReturn(Optional.of(fileSender)).when(messageWithFilesSender).getFileSender();
+			when(requestObserver.isReady()).thenReturn(true, false);
 
-			messageWithFilesSender.sendAttachments();
+			messageWithFilesSender.sendData();
 
-			verify(messageWithFilesSender, never()).createFileSenders();
+			verify(fileSender).send();
 		}
 
 		@Test
-		void shouldCallSendOnFileSender() {
-			doReturn(fileSender).when(messageWithFilesSender).buildFileSender(any());
+		@DisplayName("should not complete request if attachments not sent")
+		void shouldNotCompleteIfNotDone() {
+			doReturn(Optional.of(fileSender)).when(messageWithFilesSender).getFileSender();
+			when(requestObserver.isReady()).thenReturn(true, false);
 
-			messageWithFilesSender.sendAttachments();
+			messageWithFilesSender.sendData();
 
-			verify(fileSender).send();
+			verify(messageWithFilesSender, never()).completeRequest();
 		}
 
 		@Test
-		void shouldCallCompleteRequest() {
-			doReturn(fileSender).when(messageWithFilesSender).buildFileSender(any());
+		void shouldCompleteRequest() {
+			doReturn(Optional.empty()).when(messageWithFilesSender).getFileSender();
 
-			messageWithFilesSender.sendAttachments();
+			messageWithFilesSender.sendData();
 
 			verify(messageWithFilesSender).completeRequest();
 		}
 	}
 
 	@Nested
-	class TestCreateFileSenders {
-
-		private String attachmentId = "id1";
+	class TestGetFileSender {
 
 		@Mock
 		private FileSender fileSender;
 
-		@BeforeEach
-		void setup() {
-			doReturn(fileSender).when(messageWithFilesSender).buildFileSender(any());
-			ReflectionTestUtils.setField(messageWithFilesSender, "attachmentIds", List.of(attachmentId));
-		}
+		@Nested
+		class TestCreateFirstFileSender {
 
-		@Test
-		void shouldCalToAttachment() {
-			messageWithFilesSender.createFileSenders();
+			@BeforeEach
+			void setup() {
+				doReturn(fileSender).when(messageWithFilesSender).buildNextFileSender();
+			}
+
+			@Test
+			void shouldCallBuildNextSender() {
+				messageWithFilesSender.getFileSender();
+
+				verify(messageWithFilesSender).buildNextFileSender();
+			}
+
+			@Test
+			void shouldSetCurrentFileSender() {
+				messageWithFilesSender.getFileSender();
+
+				assertThat(messageWithFilesSender).extracting("currentFileSender").isSameAs(fileSender);
+			}
+
+			@Test
+			void shouldReturnCurrentFileSender() {
+				var result = messageWithFilesSender.getFileSender();
+
+				assertThat(result).containsSame(fileSender);
+			}
 
-			verify(toAttachment).apply(attachmentId);
 		}
 
-		@Test
-		void shouldCallBuildFileSender() {
-			messageWithFilesSender.createFileSenders();
+		@Nested
+		class TestReturnCurrentFileSender {
+
+			@BeforeEach
+			void setup() {
+				ReflectionTestUtils.setField(messageWithFilesSender, "currentFileSender", fileSender);
+			}
+
+			@Test
+			void shouldReturnCurrentFileSender() {
+				var result = messageWithFilesSender.getFileSender();
 
-			verify(messageWithFilesSender).buildFileSender(any());
+				assertThat(result).containsSame(fileSender);
+			}
+
+			@Test
+			void shouldNotCallBuildNextSender() {
+				messageWithFilesSender.getFileSender();
+
+				verify(messageWithFilesSender, never()).buildNextFileSender();
+			}
 		}
 
-		@Test
-		void shouldReturnFileSenders() {
-			var result = messageWithFilesSender.createFileSenders();
+		@Nested
+		class TestCreateNextFileSender {
+
+			@Mock
+			private FileSender nextFileSender;
+
+			@BeforeEach
+			void setup() {
+				when(fileSender.isDone()).thenReturn(true);
+				ReflectionTestUtils.setField(messageWithFilesSender, "currentFileSender", fileSender);
+				ReflectionTestUtils.setField(messageWithFilesSender, "attachmentIds", List.of("attachmentId"));
+				doReturn(nextFileSender).when(messageWithFilesSender).buildNextFileSender();
+			}
+
+			@Test
+			void shouldCallBuildNextSender() {
+				messageWithFilesSender.getFileSender();
+
+				verify(messageWithFilesSender).buildNextFileSender();
+			}
+
+			@Test
+			void shouldSetCurrentFileSender() {
+				messageWithFilesSender.getFileSender();
+
+				assertThat(messageWithFilesSender).extracting("currentFileSender").isSameAs(nextFileSender);
+			}
+
+			@Test
+			void shouldReturnCurrentFileSender() {
+				var result = messageWithFilesSender.getFileSender();
 
-			assertThat(result).containsExactly(fileSender);
+				assertThat(result).containsSame(nextFileSender);
+			}
 		}
+
 	}
 
 	@Nested
-	class TestBuildFileSender {
+	class TestBuildNextFileSender {
 
-		private String attachmentId = "id1";
+		private final String attachmentId = "id1";
 
 		@Mock
 		private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver;
 		@Mock
 		private GrpcSendBayernIdMessageRequest attachmentMetadata;
 
-		@Mock
-		private BayernIdAttachment attachment;
 		@Mock
 		private InputStream inputStream;
 
+		private final BayernIdAttachment attachment = BayernIdAttachmentTestFactory.create();
+
 		@BeforeEach
 		void setup() {
-			ReflectionTestUtils.setField(messageWithFilesSender, "requestObserver", requestObserver);
+			ReflectionTestUtils.setField(messageWithFilesSender, "attachmentIds", List.of(attachmentId));
+			when(toAttachment.apply(any())).thenReturn(attachment);
+		}
+
+		@Test
+		void shouldCallToAttachment() {
+			messageWithFilesSender.buildNextFileSender();
+
+			verify(toAttachment).apply(attachmentId);
 		}
 
 		@Test
 		void shouldSetChunkBuilder() {
-			var result = messageWithFilesSender.buildFileSender(attachment);
+			var result = messageWithFilesSender.buildNextFileSender();
 
 			assertThat(result).extracting("chunkBuilder").isSameAs(chunkBuilder);
 		}
 
 		@Test
 		void shouldSetRequestObserver() {
-			var result = messageWithFilesSender.buildFileSender(attachment);
+			ReflectionTestUtils.setField(messageWithFilesSender, "requestObserver", requestObserver);
+
+			var result = messageWithFilesSender.buildNextFileSender();
 
 			assertThat(result).extracting("requestObserver").isSameAs(requestObserver);
 		}
 
 		@Test
 		void shouldCallAttachmentMetadataMapper() {
-			ReflectionTestUtils.setField(messageWithFilesSender, "attachmentMetadataMapper", attachmentMetadataMapper);
 
-			messageWithFilesSender.buildFileSender(attachment);
+			messageWithFilesSender.buildNextFileSender();
 
 			verify(attachmentMetadataMapper).apply(attachment);
 		}
 
 		@Test
 		void shouldSetAttachmentMetadata() {
-			ReflectionTestUtils.setField(messageWithFilesSender, "attachmentMetadataMapper", attachmentMetadataMapper);
 			when(attachmentMetadataMapper.apply(any())).thenReturn(attachmentMetadata);
 
-			var result = messageWithFilesSender.buildFileSender(attachment);
+			var result = messageWithFilesSender.buildNextFileSender();
 
 			assertThat(result).extracting("metadata").isSameAs(attachmentMetadata);
 		}
 
-		@Test
-		void shouldGetContent() {
-			messageWithFilesSender.buildFileSender(attachment);
-
-			verify(attachment).getContent();
-		}
 	}
 
 	@Nested