diff --git a/include/netchan.h b/include/netchan.h
index d3e5a5e35..ff919ac4a 100644
--- a/include/netchan.h
+++ b/include/netchan.h
@@ -34,8 +34,12 @@
 #include "QF/qdefs.h"
 #include "QF/sizebuf.h"
 
-#define MAX_MSGLEN		1450		// max length of a reliable message
-#define MAX_DATAGRAM	1450		// max length of unreliable message
+//#define MAX_MSGLEN		1450		// max length of a reliable message
+//#define MAX_DATAGRAM	1450		// max length of unreliable message
+#define MAX_MSGLEN			2900
+#define MAX_DATAGRAM			2900
+#define MAX_OLD_MSGLEN		1450
+#define MAX_OLD_DATAGRAM	1450
 
 #define	PORT_ANY	-1
 
diff --git a/include/qw/protocol.h b/include/qw/protocol.h
index c8504f683..979bb69c9 100644
--- a/include/qw/protocol.h
+++ b/include/qw/protocol.h
@@ -322,6 +322,7 @@ typedef struct {
 } entity_state_t;
 
 #define	MAX_PACKET_ENTITIES			64	// doesn't count nails
+#define	MAX_EXT_PACKET_ENTITIES		128	// doesn't count nails
 #define	MAX_DEMO_PACKET_ENTITIES	196	// doesn't count nails
 typedef struct {
 	int         num_entities;
diff --git a/qtv/include/client.h b/qtv/include/client.h
index 74375b277..c2fcd2891 100644
--- a/qtv/include/client.h
+++ b/qtv/include/client.h
@@ -53,7 +53,7 @@ typedef struct client_s {
 	byte        datagram_buf[MAX_DATAGRAM];
 	qboolean    send_message;
 	frame_t     frames[UPDATE_BACKUP];
-	entity_state_t packet_entities[UPDATE_BACKUP][MAX_PACKET_ENTITIES];
+	entity_state_t packet_entities[UPDATE_BACKUP][MAX_EXT_PACKET_ENTITIES];
 
 	int         delta_sequence;
 
diff --git a/qtv/source/client.c b/qtv/source/client.c
index 06a894917..cff539633 100644
--- a/qtv/source/client.c
+++ b/qtv/source/client.c
@@ -1020,7 +1020,7 @@ write_entities (client_t *client, sizebuf_t *msg)
 //			continue;					// added to the special update list
 
 		// add to the packetentities
-		if (pack->num_entities == MAX_PACKET_ENTITIES) {
+		if (pack->num_entities == MAX_EXT_PACKET_ENTITIES) {
 			qtv_printf ("mpe overflow\n");
 			continue;					// all full
 		}
diff --git a/qw/include/server.h b/qw/include/server.h
index f39383274..498635527 100644
--- a/qw/include/server.h
+++ b/qw/include/server.h
@@ -246,6 +246,8 @@ typedef struct client_s {
 	double			last_check;
 	double			cuff_time;
 	float			stdver;
+
+	int max_packet_ents;	// either MAX_PACKET_ENTITIES or MAX_EXT_PACKET_ENTITIES
 } client_t;
 
 // a client can leave the server in one of four ways:
diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c
index 5ccdc163b..ab016015f 100644
--- a/qw/source/cl_main.c
+++ b/qw/source/cl_main.c
@@ -665,7 +665,9 @@ CL_AddQFInfoKeys (void)
 	// i   * irc
 	// p   pogo stick control
 	// t   team messages
-	static const char *cap = "pt"
+	// e   large entity/packet maximum. (128)
+	// u   large packet support. (2x normal)
+	static const char *cap = "pteu"
 #ifdef HAVE_ZLIB
 		"z"
 #endif
diff --git a/qw/source/sv_ents.c b/qw/source/sv_ents.c
index 1241e9312..aba092cb1 100644
--- a/qw/source/sv_ents.c
+++ b/qw/source/sv_ents.c
@@ -768,7 +768,7 @@ SV_WriteEntitiesToClient (delta_t *delta, sizebuf_t *msg)
 	packet_entities_t *pack;
 
 	if (delta->client) {
-		max_packet_entities = MAX_PACKET_ENTITIES;
+		max_packet_entities = delta->client->max_packet_ents;
 		stdver = delta->client->stdver;
 	}
 
diff --git a/qw/source/sv_main.c b/qw/source/sv_main.c
index 6d757fc07..e0efb69a5 100644
--- a/qw/source/sv_main.c
+++ b/qw/source/sv_main.c
@@ -102,7 +102,7 @@ cbuf_t     *sv_cbuf;
 cbuf_args_t *sv_args;
 
 client_t   *host_client;				// current client
-entity_state_t cl_entities[MAX_CLIENTS][UPDATE_BACKUP+1][MAX_PACKET_ENTITIES]; // client entities
+entity_state_t cl_entities[MAX_CLIENTS][UPDATE_BACKUP+1][MAX_EXT_PACKET_ENTITIES]; // client entities
 
 double      sv_frametime;
 double      realtime;					// without any filtering or bounding
@@ -916,9 +916,11 @@ SVC_DirectConnect (void)
 	newcl->prespawned = false;
 	newcl->spawned = false;
 
+	newcl->max_packet_ents = (strchr(Info_ValueForKey (userinfo, "*cap"), 'e') != 0) ? MAX_EXT_PACKET_ENTITIES : MAX_PACKET_ENTITIES;
+
 	newcl->datagram.allowoverflow = true;
 	newcl->datagram.data = newcl->datagram_buf;
-	newcl->datagram.maxsize = sizeof (newcl->datagram_buf);
+	newcl->datagram.maxsize = (strchr(Info_ValueForKey (userinfo, "*cap"), 'u') != 0) ? MAX_DATAGRAM : MAX_OLD_DATAGRAM;
 
 	// spectator mode can ONLY be set at join time
 	newcl->spectator = spectator;
@@ -945,6 +947,16 @@ SVC_DirectConnect (void)
 					NET_AdrToString (adr));
 	newcl->sendinfo = true;
 
+	if(newcl->max_packet_ents == MAX_EXT_PACKET_ENTITIES) {
+		SV_Printf ("Client %s (%s) supports large entity counts\n", newcl->name,
+					NET_AdrToString (adr));
+	}
+
+	if(newcl->datagram.maxsize == MAX_DATAGRAM) {
+		SV_Printf ("Client %s (%s) supports large datagram sizes\n", newcl->name,
+					NET_AdrToString (adr));
+	}
+
 	// QuakeForge stuff.
 	newcl->msecs = 0;
 	newcl->msec_cheating = 0;
diff --git a/qw/source/sv_send.c b/qw/source/sv_send.c
index eeca8cce2..12fe3e305 100644
--- a/qw/source/sv_send.c
+++ b/qw/source/sv_send.c
@@ -643,6 +643,7 @@ SV_SendClientDatagram (client_t *client)
 		SV_Printf ("WARNING: msg overflowed for %s\n", client->name);
 		SZ_Clear (&msg);
 	}
+
 	// send the datagram
 	Netchan_Transmit (&client->netchan, msg.cursize, msg.data);