diff --git a/src/seq/seqPvt.h b/src/seq/seqPvt.h
index 0d6f3dc775bdbb3b5f7734d8755a5b6309e30a42..bb0ef27695f577864dae264374d1259b1601c780 100644
--- a/src/seq/seqPvt.h
+++ b/src/seq/seqPvt.h
@@ -42,7 +42,7 @@
 #define chNum(ch)		((ch)-(ch)->sprog->chan)
 
 #define metaIx(ch,ss)		(((ch)->sprog->options&OPT_SAFE)?ssNum(ss):0)
-#define metaPtr(ch,ss)		((ch)->dbch->metaData+metaIx(ch,ss))
+#define metaPtr(ch,ss)		(((ch)->sprog->options&OPT_SAFE)?((ch)->dbch->ssMetaData+ssNum(ss)):(&(ch)->dbch->metaData))
 
 /* Generic iteration on lists */
 #define foreach(e,l)		for (e = l; e != 0; e = e->next)
@@ -117,9 +117,9 @@ struct db_channel
 	boolean		connected;	/* whether channel is connected */
 	void		*monid;		/* monitor id (supplied by PV lib) */
 	boolean		gotOneMonitor;	/* whether got at least one monitor */
-	PVMETA		*metaData;	/* array of meta data from last access,
-					   one for each state set (safe mode)
-					   or just one (unsafe mode) */
+	PVMETA		metaData;	/* meta data from last access (ca buffer) */
+	PVMETA		*ssMetaData;	/* array of meta data,
+					   one for each state set (safe mode) */
 };
 
 struct state_set
@@ -187,6 +187,7 @@ struct program_instance
 	unsigned	monitorCount;	/* number of channels monitored */
 	unsigned	firstMonitorCount; /* number of channels that received
 					   at least one monitor event */
+
 	void		*pvReqPool;	/* freeList for pv requests (has own lock) */
 	boolean		die;		/* flag set when seqStop is called */
 	epicsEventId	ready;		/* all channels connected & got 1st monitor */
@@ -210,7 +211,7 @@ struct pvreq
 
 /* seq_task.c */
 void sequencer (void *arg);
-void ss_write_buffer(SSCB *pwSS, CHAN *ch, void *val);
+void ss_write_buffer(SSCB *pwSS, CHAN *ch, void *val, PVMETA *meta);
 void ss_read_buffer(SSCB *ss, CHAN *ch);
 void seqWakeup(SPROG *sp, unsigned eventNum);
 void seqCreatePvSys(SPROG *sp);
diff --git a/src/seq/seq_ca.c b/src/seq/seq_ca.c
index 8c3b6aae1c34adbd85d180244d91304ae0aa4b96..ea120041c25d4ab14553299aadc1b2995f149f26 100644
--- a/src/seq/seq_ca.c
+++ b/src/seq/seq_ca.c
@@ -69,6 +69,8 @@ pvStat seq_connect(SPROG *sp, boolean wait)
 
 		if (ch->dbch == NULL)
 			continue;		/* skip anonymous pvs */
+		/* Note: need not take programLock because state sets not yet
+		   running and CA channels not yet created */
 		sp->assignCount += 1;
 		if (ch->monitored)
 			sp->monitorCount++;	/* do it before pvVarCreate */
@@ -213,28 +215,28 @@ static void proc_db_events(
 		return;
 	}
 
-	/* Copy value returned into user variable (can get NULL value pointer
-	   for put completion only) */
+	/* Copy value and meta data into user variable CA buffer
+	   (can get NULL value pointer for put completion only) */
 	if (value != NULL)
 	{
 		void *val = pv_value_ptr(value,type);
-                PVMETA *meta = metaPtr(ch,ss);
-
-		/* Write value to CA buffer (lock-free) */
-		ss_write_buffer(0, ch, val);
-
-		/* Copy status, severity and time stamp */
-		meta->status = *pv_status_ptr(value,type);
-		meta->severity = *pv_severity_ptr(value,type);
-		meta->timeStamp = *pv_stamp_ptr(value,type);
-
-		/* Copy error message (only when severity indicates error) */
-		if (meta->severity != pvSevrNONE)
+                PVMETA meta = {
+			*pv_stamp_ptr(value,type),
+			*pv_status_ptr(value,type),
+			*pv_severity_ptr(value,type),
+			0
+		};
+
+		/* Set error message only when severity indicates error */
+		if (meta.severity != pvSevrNONE)
 		{
 			const char *pmsg = pvVarGetMess(dbch->pvid);
 			if (!pmsg) pmsg = "unknown";
-			meta->message = pmsg;
+			meta.message = pmsg;
 		}
+
+		/* Write value and meta data to CA buffers (lock-free) */
+		ss_write_buffer(0, ch, val, &meta);
 	}
 
 	/* Wake up each state set that uses this channel in an event */
diff --git a/src/seq/seq_if.c b/src/seq/seq_if.c
index 3737404c41bbcb1085e7210edd11ab516b0d8abc..77afa101efece1620b329bf3dd00dfce2015a087 100644
--- a/src/seq/seq_if.c
+++ b/src/seq/seq_if.c
@@ -202,6 +202,7 @@ static void anonymous_put(SS_ID ss, CHAN *ch)
 		size_t size = ch->type->size;
 		char value[pv_size_n(type, ch->count)];
 		int full;
+
 		DEBUG("seq_pvPut: type=%d, size=%d, count=%d, value=%p, val_ptr=%p, buf_size=%d, q=%p\n",
 			type, size, ch->count, value, pv_value_ptr(value, type),
 			pv_size_n(type, ch->count), queue);
@@ -222,7 +223,7 @@ static void anonymous_put(SS_ID ss, CHAN *ch)
 	/* check if monitored to mirror behaviour for named PVs */
 	else if (ch->monitored)
 	{
-		ss_write_buffer(ss, ch, var);
+		ss_write_buffer(ss, ch, var, 0);
 	}
 	/* Must give varLock before calling seq_efSet, else (possible) deadlock! */
 	epicsMutexUnlock(ch->varLock);
@@ -798,11 +799,10 @@ static void *getq_cp(void *dest, const void *value, size_t elemSize)
 {
 	struct getq_cp_arg *arg = (struct getq_cp_arg *)dest;
 	CHAN	*ch = arg->ch;
-	DBCHAN	*dbch = ch->dbch;
 	PVMETA	*meta = arg->meta;
 	void	*var = arg->var;
 	pvType	type = ch->type->getType;
-	if (dbch)
+	if (ch->dbch)
 	{
 		assert(pv_is_time_type(type));
 		/* Copy status, severity and time stamp */
@@ -838,11 +838,6 @@ epicsShareFunc boolean epicsShareAPI seq_pvGetQ(SS_ID ss, VAR_ID varId)
 	/* If set, queue should be non-empty */
 	if (isSet)
 	{
-#if 0
-		pvType	type = ch->type->getType;
-		char	buffer[pv_size_n(type, ch->count)];
-		pvValue	*value = (pvValue *)buffer;
-#endif
 		struct getq_cp_arg arg = {ch, var, meta};
 		QUEUE	queue = ch->queue;
 		boolean	empty;
@@ -853,22 +848,10 @@ epicsShareFunc boolean epicsShareAPI seq_pvGetQ(SS_ID ss, VAR_ID varId)
 			errlogSevPrintf(errlogMajor,
 				"pvGetQ: event flag set but queue is empty\n");
 		}
-		else
+		else if (dbch)
 		{
-			if (dbch)
-			{
-#if 0
-				assert(pv_is_time_type(type));
-				/* Copy status, severity and time stamp */
-				meta->status = *pv_status_ptr(value,type);
-				meta->severity = *pv_severity_ptr(value,type);
-				meta->timeStamp = *pv_stamp_ptr(value,type);
-				memcpy(var, pv_value_ptr(value,type), ch->type->size * ch->count);
-#endif
-				/* If queue is now empty, clear the event flag */
-				if (seqQueueIsEmpty(queue))
-					bitClear(sp->evFlags, ev_flag);
-			}
+			/* If queue is now empty, clear the event flag */
+			if (seqQueueIsEmpty(queue)) bitClear(sp->evFlags, ev_flag);
 		}
 	}
 	epicsMutexUnlock(sp->programLock);
diff --git a/src/seq/seq_main.c b/src/seq/seq_main.c
index 34eea84aca0cbc94707c0ce0ca0a6082a34582d5..6c2cde1da1d23a65f4aea44604db979b9dbde2be 100644
--- a/src/seq/seq_main.c
+++ b/src/seq/seq_main.c
@@ -254,9 +254,7 @@ static void init_chan(SPROG *sp, CHAN *ch, seqChan *seqChan)
 			DBCHAN	*dbch = new(DBCHAN);
 			dbch->dbName = epicsStrDup(name_buffer);
 			if (sp->options & OPT_SAFE)
-				dbch->metaData = newArray(PVMETA, sp->numSS);
-			else
-				dbch->metaData = new(PVMETA);
+				dbch->ssMetaData = newArray(PVMETA, sp->numSS);
 			ch->dbch = dbch;
 		}
 		DEBUG("  assigned name=%s, expanded name=%s\n",
@@ -379,8 +377,8 @@ void seq_free(SPROG *sp)
 
 		if (ch->dbch)
 		{
-			if (ch->dbch->metaData)
-				free(ch->dbch->metaData);
+			if (ch->dbch->ssMetaData)
+				free(ch->dbch->ssMetaData);
 			if (ch->dbch->dbName != NULL)
 				free(ch->dbch->dbName);
 			free(ch->dbch);
diff --git a/src/seq/seq_qry.c b/src/seq/seq_qry.c
index eead66b187e51448fc28388eb186d4b1497d2ed6..c3e02482bcbd9553e909ac864c01c6e9a270b0f7 100644
--- a/src/seq/seq_qry.c
+++ b/src/seq/seq_qry.c
@@ -45,6 +45,7 @@ epicsShareFunc void epicsShareAPI seqShow(epicsThreadId tid)
 	if (sp->numQueues > 0)
 		printf("  queue array address = %p\n",sp->queues);
 	printf("  number of channels = %d\n", sp->numChans);
+	/* Note: need not take programLock since read-ony */
 	printf("  number of channels assigned = %d\n", sp->assignCount);
 	printf("  number of channels connected = %d\n", sp->connectCount);
 	printf("  number of channels monitored = %d\n", sp->monitorCount);
@@ -182,7 +183,7 @@ epicsShareFunc void epicsShareAPI seqChanShow(epicsThreadId tid, const char *str
 		if (dbch)
 			printf("  Assigned to \"%s\"\n", dbch->dbName);
 		else
-			printf("  Not assigned\n");
+			printf("  Anonymous\n");
 
 		if(dbch && dbch->connected)
 			printf("  Connected\n");
diff --git a/src/seq/seq_task.c b/src/seq/seq_task.c
index f0a8e65d0c9a52e47df70ca4f9a018cd87dca8a1..a50faa341ad4da9dc40b99713fd73ce47a459c5e 100644
--- a/src/seq/seq_task.c
+++ b/src/seq/seq_task.c
@@ -141,6 +141,11 @@ static void ss_read_buffer_static(SSCB *ss, CHAN *ch)
 		DEBUG("ss %s: before read %s", ss->ssName, ch->varName);
 		print_channel_value(DEBUG,ch,val);
 		memcpy(val, buf, var_size);
+		if (ch->dbch) {
+			int nss = (int)(ss - sp->ss);
+			/* structure copy */
+			ch->dbch->ssMetaData[nss] = ch->dbch->metaData;
+		}
 		DEBUG("ss %s: after read %s", ss->ssName, ch->varName);
 		print_channel_value(DEBUG,ch,val);
 	} while ((ch->busy || ss->dirty[nch])
@@ -177,7 +182,7 @@ static void ss_read_all_buffer(SPROG *sp, SSCB *ss)
  * ss_write_buffer() - Only used in safe mode.
  * Lock-free writing of variable buffer.
  */
-void ss_write_buffer(SSCB *pwSS, CHAN *ch, void *val)
+void ss_write_buffer(SSCB *pwSS, CHAN *ch, void *val, PVMETA *meta)
 {
 	SPROG	*sp = ch->sprog;
 	char	*buf = bufPtr(ch);
@@ -190,6 +195,10 @@ void ss_write_buffer(SSCB *pwSS, CHAN *ch, void *val)
 	DEBUG("ss %s: before write %s", ss_name, ch->varName);
 	print_channel_value(DEBUG,ch,buf);
 	memcpy(buf, val, var_size);
+	if (ch->dbch && meta) {
+		/* structure copy */
+		ch->dbch->metaData = *meta;
+	}
 	DEBUG("ss %s: after write %s", ss_name, ch->varName);
 	print_channel_value(DEBUG,ch,buf);
 	for (nss = 0; nss < sp->numSS; nss++)