diff --git a/src/seq/seqPvt.h b/src/seq/seqPvt.h
index 9176f83180cabe12e20d0900ed3d89a35db9db60..6f2cead9191600d24d43d54cfc7b895ae6022211 100644
--- a/src/seq/seqPvt.h
+++ b/src/seq/seqPvt.h
@@ -158,6 +158,8 @@ struct state_set
 	/* these are arrays, one for each channel */
 	epicsEventId	*getSemId;	/* semaphores for async get */
 	epicsEventId	*putSemId;	/* semaphores for async put */
+	PVREQ		**getReq;	/* get requests */
+	PVREQ		**putReq;	/* put requests */
 	/* safe mode */
 	boolean		*dirty;		/* array of flags, one for each channel */
 	SEQ_VARS	*var;		/* variable value block */
diff --git a/src/seq/seq_ca.c b/src/seq/seq_ca.c
index 3986b65025180e73a47a5ec32c1a8abd7baa4278..676d0d9d21d5b6a386ba2efb7e8808f7f18f8e2c 100644
--- a/src/seq/seq_ca.c
+++ b/src/seq/seq_ca.c
@@ -157,14 +157,16 @@ pvStat seq_connect(SPROG *sp, boolean wait)
 void seq_get_handler(
 	void *var, pvType type, unsigned count, pvValue *value, void *arg, pvStat status)
 {
-	PVREQ	*rQ = (PVREQ *)arg;
-	CHAN	*ch = rQ->ch;
+	PVREQ	*rq = (PVREQ *)arg;
+	CHAN	*ch = rq->ch;
+	SSCB	*ss = rq->ss;
 	SPROG	*sp = ch->sprog;
 
 	assert(ch->dbch != NULL);
 	freeListFree(sp->pvReqPool, arg);
-	/* Process event handling in each state set */
-	proc_db_events(value, type, ch, rQ->ss, GET_COMPLETE, status);
+	/* ignore callback if not expected, e.g. already timed out */
+	if (ss->getReq[chNum(ch)] == rq)
+		proc_db_events(value, type, ch, ss, GET_COMPLETE, status);
 }
 
 /*
@@ -174,14 +176,16 @@ void seq_get_handler(
 void seq_put_handler(
 	void *var, pvType type, unsigned count, pvValue *value, void *arg, pvStat status)
 {
-	PVREQ	*rQ = (PVREQ *)arg;
-	CHAN	*ch = rQ->ch;
+	PVREQ	*rq = (PVREQ *)arg;
+	CHAN	*ch = rq->ch;
+	SSCB	*ss = rq->ss;
 	SPROG	*sp = ch->sprog;
 
 	assert(ch->dbch != NULL);
 	freeListFree(sp->pvReqPool, arg);
-	/* Process event handling in each state set */
-	proc_db_events(value, type, ch, rQ->ss, PUT_COMPLETE, status);
+	/* ignore callback if not expected, e.g. already timed out */
+	if (ss->putReq[chNum(ch)] == rq)
+		proc_db_events(value, type, ch, ss, PUT_COMPLETE, status);
 }
 
 /*
diff --git a/src/seq/seq_if.c b/src/seq/seq_if.c
index 31b76e1eaabe5d2c1e11cbfb43d99bee86342b22..894b53185738f8a1229c2fd8f01c6916be887522 100644
--- a/src/seq/seq_if.c
+++ b/src/seq/seq_if.c
@@ -107,6 +107,9 @@ epicsShareFunc pvStat epicsShareAPI seq_pvGet(SS_ID ss, VAR_ID varId, enum compT
 			);
 			return pvStatERROR;
 		case epicsEventWaitError:
+			/* try to recover */
+			ss->getReq[varId] = NULL;
+			epicsEventSignal(getSem);
 			errlogSevPrintf(errlogFatal,
 				"pvGet: epicsEventWaitWithTimeout() failure\n");
 			return pvStatERROR;
@@ -129,6 +132,9 @@ epicsShareFunc pvStat epicsShareAPI seq_pvGet(SS_ID ss, VAR_ID varId, enum compT
 			);
 			return pvStatERROR;
 		case epicsEventWaitError:
+			/* try to recover */
+			ss->getReq[varId] = NULL;
+			epicsEventSignal(getSem);
 			errlogSevPrintf(errlogFatal,
 				"pvGet: epicsEventTryWait() failure\n");
 			return pvStatERROR;
@@ -140,6 +146,9 @@ epicsShareFunc pvStat epicsShareAPI seq_pvGet(SS_ID ss, VAR_ID varId, enum compT
 	req->ss = ss;
 	req->ch = ch;
 
+	assert(ss->getReq[varId] == NULL);
+	ss->getReq[varId] = req;
+
 	/* Perform the PV get operation with a callback routine specified.
 	   Requesting more than db channel has available is ok. */
 	status = pvVarGetCallback(
@@ -155,6 +164,7 @@ epicsShareFunc pvStat epicsShareAPI seq_pvGet(SS_ID ss, VAR_ID varId, enum compT
 		meta->message = "get failure";
 		errlogSevPrintf(errlogFatal, "pvGet(var %s, pv %s): pvVarGetCallback() failure: %s\n",
 			ch->varName, dbch->dbName, pvVarGetMess(dbch->pvid));
+		ss->getReq[varId] = NULL;
 		freeListFree(sp->pvReqPool, req);
 		epicsEventSignal(getSem);
 		check_connected(dbch, meta);
@@ -164,11 +174,15 @@ epicsShareFunc pvStat epicsShareAPI seq_pvGet(SS_ID ss, VAR_ID varId, enum compT
 	/* Synchronous: wait for completion */
 	if (compType == SYNC)
 	{
+		epicsEventWaitStatus event_status;
+
 		pvSysFlush(sp->pvSys);
-		switch (epicsEventWaitWithTimeout(getSem, tmo))
+		event_status = epicsEventWaitWithTimeout(getSem, tmo);
+		ss->getReq[varId] = NULL;
+		epicsEventSignal(getSem);
+		switch (event_status)
 		{
 		case epicsEventWaitOK:
-			epicsEventSignal(getSem);
 			status = check_connected(dbch, meta);
 			if (status) return status;
 			if (sp->options & OPT_SAFE)
@@ -222,6 +236,7 @@ epicsShareFunc boolean epicsShareAPI seq_pvGetComplete(SS_ID ss, VAR_ID varId)
 	switch (epicsEventTryWait(getSem))
 	{
 	case epicsEventWaitOK:
+		ss->getReq[varId] = NULL;
 		epicsEventSignal(getSem);
 		status = check_connected(ch->dbch, metaPtr(ch,ss));
 		/* TODO: returning either TRUE or FALSE here seems wrong. We return TRUE,
@@ -235,11 +250,14 @@ epicsShareFunc boolean epicsShareAPI seq_pvGetComplete(SS_ID ss, VAR_ID varId)
 			ss_read_buffer(ss, ch, FALSE);
 		return TRUE;
 	case epicsEventWaitTimeout:
+		epicsEventSignal(getSem);
 		return FALSE;
 	case epicsEventWaitError:
+		ss->getReq[varId] = NULL;
+		epicsEventSignal(getSem);
 		errlogSevPrintf(errlogFatal, "pvGetComplete: "
 		  "epicsEventTryWait(getSemId[%d]) failure\n", varId);
-	default:
+	default: /* pacify gcc which does not understand the we checked all possibilities */
 		return FALSE;
 	}
 }
@@ -254,7 +272,7 @@ static void *putq_cp(void *dest, const void *src, size_t elemSize)
 	struct putq_cp_arg *arg = (struct putq_cp_arg *)src;
 	CHAN *ch = arg->ch;
 
-	return memcpy(pv_value_ptr(dest, ch->type->getType),
+	return memcpy(pv_value_ptr(dest, ch->type->getType), /*BUG? should that be putType?*/
 		arg->var, ch->type->size * ch->count);
 }
 
@@ -265,7 +283,7 @@ static void anonymous_put(SS_ID ss, CHAN *ch)
 	if (ch->queue)
 	{
 		QUEUE queue = ch->queue;
-		pvType type = ch->type->getType;
+		pvType type = ch->type->getType; /*BUG? should that be putType?*/
 		size_t size = ch->type->size;
 		boolean full;
 		struct putq_cp_arg arg = {ch, var};
@@ -361,6 +379,9 @@ epicsShareFunc pvStat epicsShareAPI seq_pvPut(SS_ID ss, VAR_ID varId, enum compT
 			);
 			return pvStatERROR;
 		case epicsEventWaitError:
+			/* try to recover */
+			ss->putReq[varId] = NULL;
+			epicsEventSignal(putSem);
 			errlogSevPrintf(errlogFatal,
 				"pvPut: epicsEventWaitWithTimeout() failure\n");
 			return pvStatERROR;
@@ -385,6 +406,9 @@ epicsShareFunc pvStat epicsShareAPI seq_pvPut(SS_ID ss, VAR_ID varId, enum compT
 			);
 			return pvStatERROR;
 		case epicsEventWaitError:
+			/* try to recover */
+			ss->putReq[varId] = NULL;
+			epicsEventSignal(putSem);
 			errlogSevPrintf(errlogFatal,
 				"pvPut: epicsEventTryWait() failure\n");
 			return pvStatERROR;
@@ -418,6 +442,9 @@ epicsShareFunc pvStat epicsShareAPI seq_pvPut(SS_ID ss, VAR_ID varId, enum compT
 		req->ss = ss;
 		req->ch = ch;
 
+		assert(ss->putReq[varId] == NULL);
+		ss->putReq[varId] = req;
+
 		status = pvVarPutCallback(
 				dbch->pvid,		/* PV id */
 				ch->type->putType,	/* data type */
@@ -427,6 +454,7 @@ epicsShareFunc pvStat epicsShareAPI seq_pvPut(SS_ID ss, VAR_ID varId, enum compT
 				req);			/* user arg */
 		if (status != pvStatOK)
 		{
+			ss->putReq[varId] = NULL;
 			errlogSevPrintf(errlogFatal, "pvPut(var %s, pv %s): pvVarPutCallback() failure: %s\n",
 				ch->varName, dbch->dbName, pvVarGetMess(dbch->pvid));
 			freeListFree(sp->pvReqPool, req);
@@ -439,11 +467,15 @@ epicsShareFunc pvStat epicsShareAPI seq_pvPut(SS_ID ss, VAR_ID varId, enum compT
 	/* Synchronous: wait for completion (10s timeout) */
 	if (compType == SYNC)
 	{
+		epicsEventWaitStatus event_status;
+
 		pvSysFlush(sp->pvSys);
-		switch (epicsEventWaitWithTimeout(putSem, tmo))
+		event_status = epicsEventWaitWithTimeout(putSem, tmo);
+		ss->putReq[varId] = NULL;
+		epicsEventSignal(putSem);
+		switch (event_status)
 		{
 		case epicsEventWaitOK:
-			epicsEventSignal(putSem);
 			status = check_connected(dbch, meta);
 			if (status) return status;
 			break;
@@ -487,6 +519,7 @@ epicsShareFunc boolean epicsShareAPI seq_pvPutComplete(
 		switch (epicsEventTryWait(putSem))
 		{
 		case epicsEventWaitOK:
+			ss->putReq[varId] = NULL;
 			epicsEventSignal(putSem);
 			check_connected(ch->dbch, metaPtr(ch,ss));
 			/* TODO: returning either TRUE or FALSE here seems wrong. We return TRUE,
@@ -494,10 +527,14 @@ epicsShareFunc boolean epicsShareAPI seq_pvPutComplete(
 			   status by calling pvStatus and/or pvMessage. */
 			done = TRUE;
 			break;
+		case epicsEventWaitTimeout:
+			epicsEventSignal(putSem);
+			break;
 		case epicsEventWaitError:
+			ss->putReq[varId] = NULL;
+			epicsEventSignal(putSem);
 			errlogSevPrintf(errlogFatal, "pvPutComplete(%s): "
 			  "epicsEventTryWait(putSem[%d]) failure\n", ch->varName, varId);
-		case epicsEventWaitTimeout:
 			break;
 		}
 
diff --git a/src/seq/seq_main.c b/src/seq/seq_main.c
index d776edf7cd24124e820efb5713b15f2897915d3d..f9506d112515961f205eec470d5f5978eab28275 100644
--- a/src/seq/seq_main.c
+++ b/src/seq/seq_main.c
@@ -309,6 +309,18 @@ static boolean init_sscb(SPROG *sp, SSCB *ss, seqSS *seqSS)
 			errlogSevPrintf(errlogFatal, "init_sscb: calloc failed\n");
 			return FALSE;
 		}
+		ss->getReq = newArray(PVREQ*, sp->numChans);
+		if (!ss->getReq)
+		{
+			errlogSevPrintf(errlogFatal, "init_sscb: calloc failed\n");
+			return FALSE;
+		}
+		ss->putReq = newArray(PVREQ*, sp->numChans);
+		if (!ss->putReq)
+		{
+			errlogSevPrintf(errlogFatal, "init_sscb: calloc failed\n");
+			return FALSE;
+		}
 	}
 	for (nch = 0; nch < sp->numChans; nch++)
 	{
@@ -324,6 +336,7 @@ static boolean init_sscb(SPROG *sp, SSCB *ss, seqSS *seqSS)
 			errlogSevPrintf(errlogFatal, "init_sscb: epicsEventCreate failed\n");
 			return FALSE;
 		}
+		/* note: do not pre-allocate request structures */
 	}
 	ss->dead = epicsEventCreate(epicsEventEmpty);
 	if (!ss->dead)